Home | History | Annotate | Download | only in tests
      1 /*
      2  * Check decoding of utimensat syscall.
      3  *
      4  * Copyright (c) 2015-2017 Dmitry V. Levin <ldv (at) altlinux.org>
      5  * Copyright (c) 2015-2018 The strace developers.
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. The name of the author may not be used to endorse or promote products
     17  *    derived from this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "tests.h"
     32 #include <fcntl.h>
     33 #include <stdint.h>
     34 #include <stdio.h>
     35 #include <sys/stat.h>
     36 #include <sys/time.h>
     37 #include <unistd.h>
     38 #include <asm/unistd.h>
     39 
     40 #if defined __NR_utimensat && defined UTIME_NOW && defined UTIME_OMIT
     41 
     42 #if SIZEOF_KERNEL_LONG_T == 4
     43 #  define big_tv_sec "-559038737"
     44 #  define huge_tv_sec "-559038737"
     45 # else
     46 #  define big_tv_sec "3735928559"
     47 #  define huge_tv_sec "-3819351491602432273"
     48 # endif
     49 
     50 # if XLAT_RAW
     51 #  define str_at_fdcwd			"-100"
     52 #  define str_at_symlink_nofollow	"0x100"
     53 #  define str_at_removedir		"0x200"
     54 #  define str_flags1			"0x600"
     55 #  define str_flags2			"0xffffffff"
     56 #  define str_utime_now_omit \
     57 	"[{tv_sec=" big_tv_sec ", tv_nsec=1073741823}, " \
     58 	"{tv_sec=" huge_tv_sec ", tv_nsec=1073741822}]"
     59 # elif XLAT_VERBOSE
     60 #  define str_at_fdcwd			"-100 /* AT_FDCWD */"
     61 #  define str_at_symlink_nofollow	"0x100 /* AT_SYMLINK_NOFOLLOW */"
     62 #  define str_at_removedir		"0x200 /* AT_REMOVEDIR */"
     63 #  define str_flags1 \
     64 	"0x600 /* AT_REMOVEDIR|AT_SYMLINK_FOLLOW */"
     65 #  define str_flags2 \
     66 	"0xffffffff /* AT_SYMLINK_NOFOLLOW|AT_REMOVEDIR|AT_SYMLINK_FOLLOW" \
     67 	"|AT_NO_AUTOMOUNT|AT_EMPTY_PATH|0xffffe0ff */"
     68 #  define str_utime_now_omit \
     69 	"[{tv_sec=" big_tv_sec ", tv_nsec=1073741823} /* UTIME_NOW */, " \
     70 	"{tv_sec=" huge_tv_sec ", tv_nsec=1073741822} /* UTIME_OMIT */]"
     71 # else
     72 #  define str_at_fdcwd			"AT_FDCWD"
     73 #  define str_at_symlink_nofollow	"AT_SYMLINK_NOFOLLOW"
     74 #  define str_at_removedir		"AT_REMOVEDIR"
     75 #  define str_flags1			"AT_REMOVEDIR|AT_SYMLINK_FOLLOW"
     76 #  define str_flags2 \
     77 	"AT_SYMLINK_NOFOLLOW|AT_REMOVEDIR|AT_SYMLINK_FOLLOW" \
     78 	"|AT_NO_AUTOMOUNT|AT_EMPTY_PATH|0xffffe0ff"
     79 #  define str_utime_now_omit		"[UTIME_NOW, UTIME_OMIT]"
     80 # endif
     81 
     82 static void
     83 print_ts(const struct timespec *ts)
     84 {
     85 	printf("{tv_sec=%lld, tv_nsec=%llu}", (long long) ts->tv_sec,
     86 		zero_extend_signed_to_ull(ts->tv_nsec));
     87 	print_time_t_nsec(ts->tv_sec,
     88 			  zero_extend_signed_to_ull(ts->tv_nsec), 1);
     89 }
     90 
     91 static const char *errstr;
     92 
     93 static long
     94 k_utimensat(const kernel_ulong_t dirfd,
     95 	    const kernel_ulong_t pathname,
     96 	    const kernel_ulong_t times,
     97 	    const kernel_ulong_t flags)
     98 {
     99 	long rc = syscall(__NR_utimensat, dirfd, pathname, times, flags);
    100 	errstr = sprintrc(rc);
    101 	return rc;
    102 }
    103 
    104 int
    105 main(void)
    106 {
    107 	static const kernel_ulong_t bogus_fd =
    108 		(kernel_ulong_t) 0xbadc0deddeadbeef;
    109 	static const kernel_ulong_t kfdcwd =
    110 		(kernel_ulong_t) 0xdefaced00000000 | -100U;
    111 	static const char proto_fname[] = "utimensat\nfilename";
    112 	static const char qname[] = "\"utimensat\\nfilename\"";
    113 
    114 	char *const fname = tail_memdup(proto_fname, sizeof(proto_fname));
    115 	const kernel_ulong_t kfname = (uintptr_t) fname;
    116 	struct timespec *const ts = tail_alloc(sizeof(*ts) * 2);
    117 
    118 	(void) close(0);
    119 
    120 	/* dirfd */
    121 	k_utimensat(0, kfname, 0, 0);
    122 	printf("utimensat(0, %s, NULL, 0) = %s\n", qname, errstr);
    123 
    124 	k_utimensat(bogus_fd, kfname, 0, 0);
    125 	printf("utimensat(%d, %s, NULL, 0) = %s\n",
    126 	       (int) bogus_fd, qname, errstr);
    127 
    128 	k_utimensat(-100U, kfname, 0, 0);
    129 	printf("utimensat(" str_at_fdcwd ", %s, NULL, 0) = %s\n", qname, errstr);
    130 
    131 	k_utimensat(kfdcwd, kfname, 0, 0);
    132 	printf("utimensat(" str_at_fdcwd ", %s, NULL, 0) = %s\n", qname, errstr);
    133 
    134 	/* pathname */
    135 	k_utimensat(kfdcwd, 0, 0, 0);
    136 	printf("utimensat(" str_at_fdcwd ", NULL, NULL, 0) = %s\n", errstr);
    137 
    138 	k_utimensat(kfdcwd, kfname + sizeof(proto_fname) - 1, 0, 0);
    139 	printf("utimensat(" str_at_fdcwd ", \"\", NULL, 0) = %s\n", errstr);
    140 
    141 	fname[sizeof(proto_fname) - 1] = '+';
    142 	k_utimensat(kfdcwd, kfname, 0, 0);
    143 	fname[sizeof(proto_fname) - 1] = '\0';
    144 	printf("utimensat(" str_at_fdcwd ", %p, NULL, 0) = %s\n", fname, errstr);
    145 
    146 	if (F8ILL_KULONG_SUPPORTED) {
    147 		k_utimensat(kfdcwd, f8ill_ptr_to_kulong(fname), 0, 0);
    148 		printf("utimensat(" str_at_fdcwd ", %#jx, NULL, 0) = %s\n",
    149 		       (uintmax_t) f8ill_ptr_to_kulong(fname), errstr);
    150 	}
    151 
    152 	/* times */
    153 	k_utimensat(kfdcwd, kfname, (uintptr_t) (ts + 1), 0);
    154 	printf("utimensat(" str_at_fdcwd ", %s, %p, 0) = %s\n",
    155 	       qname, ts + 1, errstr);
    156 
    157 	k_utimensat(kfdcwd, kfname, (uintptr_t) (ts + 2), 0);
    158 	printf("utimensat(" str_at_fdcwd ", %s, %p, 0)"
    159 	       " = %s\n", qname, ts + 2, errstr);
    160 
    161 	ts[0].tv_sec = 1492358706;
    162 	ts[0].tv_nsec = 123456789;
    163 	ts[1].tv_sec = 1492357068;
    164 	ts[1].tv_nsec = 234567890;
    165 
    166 	k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
    167 	printf("utimensat(" str_at_fdcwd ", %s, [", qname);
    168 	print_ts(&ts[0]);
    169 	printf(", ");
    170 	print_ts(&ts[1]);
    171 	printf("], " str_at_symlink_nofollow ") = %s\n", errstr);
    172 
    173 	ts[0].tv_sec = -1;
    174 	ts[0].tv_nsec = 2000000000;
    175 	ts[1].tv_sec = (time_t) -0x100000001LL;
    176 	ts[1].tv_nsec = 2345678900U;
    177 
    178 	k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
    179 	printf("utimensat(" str_at_fdcwd ", %s, [", qname);
    180 	print_ts(&ts[0]);
    181 	printf(", ");
    182 	print_ts(&ts[1]);
    183 	printf("], " str_at_symlink_nofollow ") = %s\n", errstr);
    184 
    185 	ts[0].tv_sec = 0;
    186 	ts[0].tv_nsec = 0;
    187 	ts[1].tv_sec = (time_t) 0xcafef00ddeadbeefLL;
    188 	ts[1].tv_nsec = 0;
    189 
    190 	k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
    191 	printf("utimensat(" str_at_fdcwd ", %s, [", qname);
    192 	print_ts(&ts[0]);
    193 	printf(", ");
    194 	print_ts(&ts[1]);
    195 	printf("], " str_at_symlink_nofollow ") = %s\n", errstr);
    196 
    197 	ts[0].tv_sec = 0xdeadbeefU;
    198 	ts[0].tv_nsec = 0xfacefeedU;
    199 	ts[1].tv_sec = (time_t) 0xcafef00ddeadbeefLL;
    200 	ts[1].tv_nsec = (long) 0xbadc0dedfacefeedLL;
    201 
    202 	k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
    203 	printf("utimensat(" str_at_fdcwd ", %s, [", qname);
    204 	print_ts(&ts[0]);
    205 	printf(", ");
    206 	print_ts(&ts[1]);
    207 	printf("], " str_at_symlink_nofollow ") = %s\n", errstr);
    208 
    209 	ts[0].tv_nsec = UTIME_NOW;
    210 	ts[1].tv_nsec = UTIME_OMIT;
    211 	k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
    212 	printf("utimensat(" str_at_fdcwd ", %s, " str_utime_now_omit
    213 	       ", " str_at_symlink_nofollow ") = %s\n", qname, errstr);
    214 
    215 	if (F8ILL_KULONG_SUPPORTED) {
    216 		k_utimensat(kfdcwd, kfname, f8ill_ptr_to_kulong(ts), 0);
    217 		printf("utimensat(" str_at_fdcwd ", %s, %#jx, 0) = %s\n",
    218 		       qname, (uintmax_t) f8ill_ptr_to_kulong(ts), errstr);
    219 	}
    220 
    221 	/* flags */
    222 	k_utimensat(kfdcwd, kfname, (uintptr_t) ts,
    223 		    (kernel_ulong_t) 0xdefaced00000200);
    224 	printf("utimensat(" str_at_fdcwd ", %s, " str_utime_now_omit
    225 	       ", " str_at_removedir ") = %s\n",
    226 	       qname, errstr);
    227 
    228 	k_utimensat(kfdcwd, kfname, (uintptr_t) ts,
    229 		    (kernel_ulong_t) 0xdefaced00000600);
    230 	printf("utimensat(" str_at_fdcwd ", %s, " str_utime_now_omit
    231 	       ", " str_flags1 ") = %s\n",
    232 	       qname, errstr);
    233 
    234 	k_utimensat(kfdcwd, kfname, (uintptr_t) ts, (kernel_ulong_t) -1ULL);
    235 	printf("utimensat(" str_at_fdcwd ", %s, " str_utime_now_omit
    236 	       ", " str_flags2 ") = %s\n",
    237 	       qname, errstr);
    238 
    239 	puts("+++ exited with 0 +++");
    240 	return 0;
    241 }
    242 
    243 #else
    244 
    245 SKIP_MAIN_UNDEFINED("__NR_utimensat && UTIME_NOW && UTIME_OMIT")
    246 
    247 #endif
    248