1 /* 2 * Check decoding of futimesat syscall. 3 * 4 * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "tests.h" 31 #include <asm/unistd.h> 32 33 #ifdef __NR_futimesat 34 35 # include <stdint.h> 36 # include <stdio.h> 37 # include <sys/time.h> 38 # include <unistd.h> 39 40 static void 41 print_tv(const struct timeval *tv) 42 { 43 printf("{tv_sec=%lld, tv_usec=%llu}", 44 (long long) tv->tv_sec, 45 zero_extend_signed_to_ull(tv->tv_usec)); 46 print_time_t_usec(tv->tv_sec, 47 zero_extend_signed_to_ull(tv->tv_usec), 1); 48 } 49 50 static const char *errstr; 51 52 static long 53 k_futimesat(const kernel_ulong_t dirfd, 54 const kernel_ulong_t pathname, 55 const kernel_ulong_t times) 56 { 57 long rc = syscall(__NR_futimesat, dirfd, pathname, times); 58 errstr = sprintrc(rc); 59 return rc; 60 } 61 62 int 63 main(void) 64 { 65 static const kernel_ulong_t bogus_fd = 66 (kernel_ulong_t) 0xbadfaceddeadbeaf; 67 static const kernel_ulong_t kfdcwd = 68 (kernel_ulong_t) 0xdefaced00000000 | -100U; 69 static const char proto_fname[] = "futimesat_sample"; 70 static const char qname[] = "\"futimesat_sample\""; 71 72 char *const fname = tail_memdup(proto_fname, sizeof(proto_fname)); 73 const kernel_ulong_t kfname = (uintptr_t) fname; 74 struct timeval *const tv = tail_alloc(sizeof(*tv) * 2); 75 76 (void) close(0); 77 78 /* dirfd */ 79 k_futimesat(0, kfname, 0); 80 printf("futimesat(0, %s, NULL) = %s\n", qname, errstr); 81 82 k_futimesat(bogus_fd, kfname, 0); 83 printf("futimesat(%d, %s, NULL) = %s\n", (int) bogus_fd, qname, errstr); 84 85 k_futimesat(-100U, kfname, 0); 86 printf("futimesat(AT_FDCWD, %s, NULL) = %s\n", qname, errstr); 87 88 k_futimesat(kfdcwd, kfname, 0); 89 printf("futimesat(AT_FDCWD, %s, NULL) = %s\n", qname, errstr); 90 91 /* pathname */ 92 k_futimesat(kfdcwd, 0, 0); 93 printf("futimesat(AT_FDCWD, NULL, NULL) = %s\n", errstr); 94 95 k_futimesat(kfdcwd, kfname + sizeof(proto_fname) - 1, 0); 96 printf("futimesat(AT_FDCWD, \"\", NULL) = %s\n", errstr); 97 98 fname[sizeof(proto_fname) - 1] = '+'; 99 k_futimesat(kfdcwd, kfname, 0); 100 fname[sizeof(proto_fname) - 1] = '\0'; 101 printf("futimesat(AT_FDCWD, %p, NULL) = %s\n", fname, errstr); 102 103 if (F8ILL_KULONG_SUPPORTED) { 104 k_futimesat(kfdcwd, f8ill_ptr_to_kulong(fname), 0); 105 printf("futimesat(AT_FDCWD, %#jx, NULL) = %s\n", 106 (uintmax_t) f8ill_ptr_to_kulong(fname), errstr); 107 } 108 109 /* times */ 110 k_futimesat(kfdcwd, kfname, (uintptr_t) (tv + 1)); 111 printf("futimesat(AT_FDCWD, %s, %p) = %s\n", 112 qname, tv + 1, errstr); 113 114 k_futimesat(kfdcwd, kfname, (uintptr_t) (tv + 2)); 115 printf("futimesat(AT_FDCWD, %s, %p) = %s\n", 116 qname, tv + 2, errstr); 117 118 tv[0].tv_sec = 0xdeadbeefU; 119 tv[0].tv_usec = 0xfacefeedU; 120 tv[1].tv_sec = (time_t) 0xcafef00ddeadbeefLL; 121 tv[1].tv_usec = (suseconds_t) 0xbadc0dedfacefeedLL; 122 123 k_futimesat(kfdcwd, kfname, (uintptr_t) tv); 124 printf("futimesat(AT_FDCWD, %s, [", qname); 125 print_tv(&tv[0]); 126 printf(", "); 127 print_tv(&tv[1]); 128 printf("]) = %s\n", errstr); 129 130 tv[0].tv_sec = 1492356708; 131 tv[0].tv_usec = 567891234; 132 tv[1].tv_sec = 1492357086; 133 tv[1].tv_usec = 678902345; 134 135 k_futimesat(kfdcwd, kfname, (uintptr_t) tv); 136 printf("futimesat(AT_FDCWD, %s, [", qname); 137 print_tv(&tv[0]); 138 printf(", "); 139 print_tv(&tv[1]); 140 printf("]) = %s\n", errstr); 141 142 tv[0].tv_usec = 567891; 143 tv[1].tv_usec = 678902; 144 145 k_futimesat(kfdcwd, kfname, (uintptr_t) tv); 146 printf("futimesat(AT_FDCWD, %s, [", qname); 147 print_tv(&tv[0]); 148 printf(", "); 149 print_tv(&tv[1]); 150 printf("]) = %s\n", errstr); 151 152 if (F8ILL_KULONG_SUPPORTED) { 153 k_futimesat(kfdcwd, kfname, f8ill_ptr_to_kulong(tv)); 154 printf("futimesat(AT_FDCWD, %s, %#jx) = %s\n", 155 qname, (uintmax_t) f8ill_ptr_to_kulong(tv), errstr); 156 } 157 158 puts("+++ exited with 0 +++"); 159 return 0; 160 } 161 162 #else 163 164 SKIP_MAIN_UNDEFINED("__NR_futimesat") 165 166 #endif 167