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