Home | History | Annotate | Download | only in tests-m32
      1 /*
      2  * Check decoding of fanotify_mark syscall.
      3  *
      4  * Copyright (c) 2015-2016 Dmitry V. Levin <ldv (at) altlinux.org>
      5  * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr (at) gmail.com>
      6  * Copyright (c) 2015-2018 The strace developers.
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. The name of the author may not be used to endorse or promote products
     18  *    derived from this software without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include "tests.h"
     33 
     34 #include <asm/unistd.h>
     35 
     36 #if defined HAVE_SYS_FANOTIFY_H && defined HAVE_FANOTIFY_MARK && \
     37 	defined __NR_fanotify_mark
     38 
     39 # include <limits.h>
     40 # include <stdio.h>
     41 # include <unistd.h>
     42 # include <sys/fanotify.h>
     43 
     44 #if XLAT_RAW
     45 # define str_fan_mark_add	"0x1"
     46 # define str_fan_modify_ondir	"0x40000002"
     47 # define str_at_fdcwd		"-100"
     48 #elif XLAT_VERBOSE
     49 # define str_fan_mark_add	"0x1 /* FAN_MARK_ADD */"
     50 # define str_fan_modify_ondir	"0x40000002 /* FAN_MODIFY|FAN_ONDIR */"
     51 # define str_at_fdcwd		"-100 /* AT_FDCWD */"
     52 #else
     53 # define str_fan_mark_add	"FAN_MARK_ADD"
     54 # define str_fan_modify_ondir	"FAN_MODIFY|FAN_ONDIR"
     55 # define str_at_fdcwd		"AT_FDCWD"
     56 #endif
     57 
     58 /* Performs fanotify_mark call via the syscall interface. */
     59 static void
     60 do_call(kernel_ulong_t fd, kernel_ulong_t flags, const char *flags_str,
     61 	uint64_t mask, const char *mask_str, kernel_ulong_t dirfd,
     62 	const char *dirfd_str, kernel_ulong_t path, const char *path_str)
     63 {
     64 	long rc;
     65 
     66 	rc = syscall(__NR_fanotify_mark, fd, flags,
     67 # if (LONG_MAX > INT_MAX) \
     68   || (defined __x86_64__ && defined __ILP32__) \
     69   || defined LINUX_MIPSN32
     70 		mask,
     71 # else
     72 /* arch/parisc/kernel/sys_parisc32.c, commit ab8a261b */
     73 #  ifdef HPPA
     74 		LL_VAL_TO_PAIR((mask << 32) | (mask >> 32)),
     75 #  else
     76 		LL_VAL_TO_PAIR(mask),
     77 #  endif
     78 # endif
     79 		dirfd, path);
     80 
     81 	printf("fanotify_mark(%d, %s, %s, %s, %s) = %s\n",
     82 	       (int) fd, flags_str, mask_str, dirfd_str, path_str,
     83 	       sprintrc(rc));
     84 }
     85 
     86 struct strval {
     87 	kernel_ulong_t val;
     88 	const char *str;
     89 };
     90 
     91 struct strval64 {
     92 	uint64_t val;
     93 	const char *str;
     94 };
     95 
     96 #define STR16 "0123456789abcdef"
     97 #define STR64 STR16 STR16 STR16 STR16
     98 
     99 int
    100 main(void)
    101 {
    102 	enum {
    103 		PATH1_SIZE = 64,
    104 	};
    105 
    106 	static const kernel_ulong_t fds[] = {
    107 		(kernel_ulong_t) 0xdeadfeed12345678ULL,
    108 		F8ILL_KULONG_MASK,
    109 		(kernel_ulong_t) 0xdeb0d1edffffffffULL,
    110 	};
    111 	static const struct strval flags[] = {
    112 		{ F8ILL_KULONG_MASK, "0" },
    113 		{ (kernel_ulong_t) 0xdec0deddefaced00ULL,
    114 			"0xefaced00"
    115 #if !XLAT_RAW
    116 			" /* FAN_MARK_??? */"
    117 #endif
    118 			},
    119 		{ (kernel_ulong_t) 0xda7a105700000040ULL,
    120 #if XLAT_RAW
    121 			"0x40"
    122 #elif XLAT_VERBOSE
    123 			"0x40 /* FAN_MARK_IGNORED_SURV_MODIFY */"
    124 #else
    125 			"FAN_MARK_IGNORED_SURV_MODIFY"
    126 #endif
    127 			},
    128 		{ (kernel_ulong_t) 0xbadc0deddeadfeedULL,
    129 #if XLAT_RAW || XLAT_VERBOSE
    130 			"0xdeadfeed"
    131 #endif
    132 #if XLAT_VERBOSE
    133 			" /* "
    134 #endif
    135 #if !XLAT_RAW
    136 			"FAN_MARK_ADD|FAN_MARK_DONT_FOLLOW|FAN_MARK_ONLYDIR|"
    137 			"FAN_MARK_IGNORED_MASK|FAN_MARK_IGNORED_SURV_MODIFY|"
    138 			"FAN_MARK_FLUSH|0xdeadfe00"
    139 #endif
    140 #if XLAT_VERBOSE
    141 			" */"
    142 #endif
    143 			},
    144 	};
    145 	static const struct strval64 masks[] = {
    146 		{ ARG_ULL_STR(0) },
    147 		{ 0xdeadfeedfacebeefULL,
    148 #if XLAT_RAW || XLAT_VERBOSE
    149 			"0xdeadfeedfacebeef"
    150 #endif
    151 #if XLAT_VERBOSE
    152 			" /* "
    153 #endif
    154 #if !XLAT_RAW
    155 			"FAN_ACCESS|FAN_MODIFY|FAN_CLOSE_WRITE|FAN_OPEN|"
    156 			"FAN_ACCESS_PERM|FAN_ONDIR|FAN_EVENT_ON_CHILD|"
    157 			"0xdeadfeedb2ccbec4"
    158 #endif
    159 #if XLAT_VERBOSE
    160 			" */"
    161 #endif
    162 			},
    163 		{ ARG_ULL_STR(0xffffffffb7fcbfc4)
    164 #if !XLAT_RAW
    165 			" /* FAN_??? */"
    166 #endif
    167 			},
    168 	};
    169 	static const struct strval dirfds[] = {
    170 		{ (kernel_ulong_t) 0xfacefeed00000001ULL, "1" },
    171 		{ (kernel_ulong_t) 0xdec0ded0ffffffffULL,
    172 #if XLAT_RAW
    173 			"-1"
    174 #elif XLAT_VERBOSE
    175 			"-1 /* FAN_NOFD */"
    176 #else
    177 			"FAN_NOFD"
    178 #endif
    179 			},
    180 		{ (kernel_ulong_t) 0xbadfacedffffff9cULL, str_at_fdcwd },
    181 		{ (kernel_ulong_t) 0xdefaced1beeff00dULL, "-1091571699" },
    182 	};
    183 	static const char str64[] = STR64;
    184 
    185 	static char bogus_path1_addr[sizeof("0x") + sizeof(void *) * 2];
    186 	static char bogus_path1_after_addr[sizeof("0x") + sizeof(void *) * 2];
    187 
    188 	char *bogus_path1 = tail_memdup(str64, PATH1_SIZE);
    189 	char *bogus_path2 = tail_memdup(str64, sizeof(str64));
    190 
    191 	struct strval paths[] = {
    192 		{ (kernel_ulong_t) 0, "NULL" },
    193 		{ (kernel_ulong_t) (uintptr_t) (bogus_path1 + PATH1_SIZE),
    194 			bogus_path1_after_addr },
    195 		{ (kernel_ulong_t) (uintptr_t) bogus_path1, bogus_path1_addr },
    196 		{ (kernel_ulong_t) (uintptr_t) bogus_path2, "\"" STR64 "\"" },
    197 	};
    198 
    199 	unsigned int i;
    200 	unsigned int j;
    201 	unsigned int k;
    202 	unsigned int l;
    203 	unsigned int m;
    204 	int rc;
    205 
    206 
    207 	snprintf(bogus_path1_addr, sizeof(bogus_path1_addr), "%p", bogus_path1);
    208 	snprintf(bogus_path1_after_addr, sizeof(bogus_path1_after_addr), "%p",
    209 		bogus_path1 + PATH1_SIZE);
    210 
    211 	rc = fanotify_mark(-1, FAN_MARK_ADD, FAN_MODIFY | FAN_ONDIR,
    212 			       -100, ".");
    213 	printf("fanotify_mark(-1, %s, %s, %s, \".\") = %s\n",
    214 	       str_fan_mark_add, str_fan_modify_ondir, str_at_fdcwd,
    215 	       sprintrc(rc));
    216 
    217 	for (i = 0; i < ARRAY_SIZE(fds); i++) {
    218 		for (j = 0; j < ARRAY_SIZE(flags); j++) {
    219 			for (k = 0; k < ARRAY_SIZE(masks); k++) {
    220 				for (l = 0; l < ARRAY_SIZE(dirfds); l++) {
    221 					for (m = 0; m < ARRAY_SIZE(paths); m++)
    222 						do_call(fds[i],
    223 							flags[j].val,
    224 							flags[j].str,
    225 							masks[k].val,
    226 							masks[k].str,
    227 							dirfds[l].val,
    228 							dirfds[l].str,
    229 							paths[m].val,
    230 							paths[m].str);
    231 				}
    232 			}
    233 		}
    234 	}
    235 
    236 	puts("+++ exited with 0 +++");
    237 	return 0;
    238 }
    239 
    240 #else
    241 
    242 SKIP_MAIN_UNDEFINED("HAVE_SYS_FANOTIFY_H && HAVE_FANOTIFY_MARK && "
    243 		    "__NR_fanotify_mark")
    244 
    245 #endif
    246