]> granicus.if.org Git - strace/blob - tests/fanotify_mark.c
tests: change the license to GPL-2.0-or-later
[strace] / tests / fanotify_mark.c
1 /*
2  * Check decoding of fanotify_mark syscall.
3  *
4  * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
5  * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
6  * Copyright (c) 2015-2018 The strace developers.
7  * All rights reserved.
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11
12 #include "tests.h"
13
14 #include <asm/unistd.h>
15
16 #if defined HAVE_SYS_FANOTIFY_H && defined HAVE_FANOTIFY_MARK && \
17         defined __NR_fanotify_mark
18
19 # include <limits.h>
20 # include <stdio.h>
21 # include <unistd.h>
22 # include <sys/fanotify.h>
23
24 #if XLAT_RAW
25 # define str_fan_mark_add       "0x1"
26 # define str_fan_modify_ondir   "0x40000002"
27 # define str_at_fdcwd           "-100"
28 #elif XLAT_VERBOSE
29 # define str_fan_mark_add       "0x1 /* FAN_MARK_ADD */"
30 # define str_fan_modify_ondir   "0x40000002 /* FAN_MODIFY|FAN_ONDIR */"
31 # define str_at_fdcwd           "-100 /* AT_FDCWD */"
32 #else
33 # define str_fan_mark_add       "FAN_MARK_ADD"
34 # define str_fan_modify_ondir   "FAN_MODIFY|FAN_ONDIR"
35 # define str_at_fdcwd           "AT_FDCWD"
36 #endif
37
38 /* Performs fanotify_mark call via the syscall interface. */
39 static void
40 do_call(kernel_ulong_t fd, kernel_ulong_t flags, const char *flags_str,
41         uint64_t mask, const char *mask_str, kernel_ulong_t dirfd,
42         const char *dirfd_str, kernel_ulong_t path, const char *path_str)
43 {
44         long rc;
45
46         rc = syscall(__NR_fanotify_mark, fd, flags,
47 # if (LONG_MAX > INT_MAX) \
48   || (defined __x86_64__ && defined __ILP32__) \
49   || defined LINUX_MIPSN32
50                 mask,
51 # else
52 /* arch/parisc/kernel/sys_parisc32.c, commit ab8a261b */
53 #  ifdef HPPA
54                 LL_VAL_TO_PAIR((mask << 32) | (mask >> 32)),
55 #  else
56                 LL_VAL_TO_PAIR(mask),
57 #  endif
58 # endif
59                 dirfd, path);
60
61         printf("fanotify_mark(%d, %s, %s, %s, %s) = %s\n",
62                (int) fd, flags_str, mask_str, dirfd_str, path_str,
63                sprintrc(rc));
64 }
65
66 struct strval {
67         kernel_ulong_t val;
68         const char *str;
69 };
70
71 struct strval64 {
72         uint64_t val;
73         const char *str;
74 };
75
76 #define STR16 "0123456789abcdef"
77 #define STR64 STR16 STR16 STR16 STR16
78
79 int
80 main(void)
81 {
82         enum {
83                 PATH1_SIZE = 64,
84         };
85
86         static const kernel_ulong_t fds[] = {
87                 (kernel_ulong_t) 0xdeadfeed12345678ULL,
88                 F8ILL_KULONG_MASK,
89                 (kernel_ulong_t) 0xdeb0d1edffffffffULL,
90         };
91         static const struct strval flags[] = {
92                 { F8ILL_KULONG_MASK, "0" },
93                 { (kernel_ulong_t) 0xdec0deddefaced00ULL,
94                         "0xefaced00"
95 #if !XLAT_RAW
96                         " /* FAN_MARK_??? */"
97 #endif
98                         },
99                 { (kernel_ulong_t) 0xda7a105700000040ULL,
100 #if XLAT_RAW
101                         "0x40"
102 #elif XLAT_VERBOSE
103                         "0x40 /* FAN_MARK_IGNORED_SURV_MODIFY */"
104 #else
105                         "FAN_MARK_IGNORED_SURV_MODIFY"
106 #endif
107                         },
108                 { (kernel_ulong_t) 0xbadc0deddeadfeedULL,
109 #if XLAT_RAW || XLAT_VERBOSE
110                         "0xdeadfeed"
111 #endif
112 #if XLAT_VERBOSE
113                         " /* "
114 #endif
115 #if !XLAT_RAW
116                         "FAN_MARK_ADD|FAN_MARK_DONT_FOLLOW|FAN_MARK_ONLYDIR|"
117                         "FAN_MARK_IGNORED_MASK|FAN_MARK_IGNORED_SURV_MODIFY|"
118                         "FAN_MARK_FLUSH|0xdeadfe00"
119 #endif
120 #if XLAT_VERBOSE
121                         " */"
122 #endif
123                         },
124         };
125         static const struct strval64 masks[] = {
126                 { ARG_ULL_STR(0) },
127                 { 0xdeadfeedfacebeefULL,
128 #if XLAT_RAW || XLAT_VERBOSE
129                         "0xdeadfeedfacebeef"
130 #endif
131 #if XLAT_VERBOSE
132                         " /* "
133 #endif
134 #if !XLAT_RAW
135                         "FAN_ACCESS|FAN_MODIFY|FAN_CLOSE_WRITE|FAN_OPEN|"
136                         "FAN_ACCESS_PERM|FAN_ONDIR|FAN_EVENT_ON_CHILD|"
137                         "0xdeadfeedb2ccbec4"
138 #endif
139 #if XLAT_VERBOSE
140                         " */"
141 #endif
142                         },
143                 { ARG_ULL_STR(0xffffffffb7fcbfc4)
144 #if !XLAT_RAW
145                         " /* FAN_??? */"
146 #endif
147                         },
148         };
149         static const struct strval dirfds[] = {
150                 { (kernel_ulong_t) 0xfacefeed00000001ULL, "1" },
151                 { (kernel_ulong_t) 0xdec0ded0ffffffffULL,
152 #if XLAT_RAW
153                         "-1"
154 #elif XLAT_VERBOSE
155                         "-1 /* FAN_NOFD */"
156 #else
157                         "FAN_NOFD"
158 #endif
159                         },
160                 { (kernel_ulong_t) 0xbadfacedffffff9cULL, str_at_fdcwd },
161                 { (kernel_ulong_t) 0xdefaced1beeff00dULL, "-1091571699" },
162         };
163         static const char str64[] = STR64;
164
165         static char bogus_path1_addr[sizeof("0x") + sizeof(void *) * 2];
166         static char bogus_path1_after_addr[sizeof("0x") + sizeof(void *) * 2];
167
168         char *bogus_path1 = tail_memdup(str64, PATH1_SIZE);
169         char *bogus_path2 = tail_memdup(str64, sizeof(str64));
170
171         struct strval paths[] = {
172                 { (kernel_ulong_t) 0, "NULL" },
173                 { (kernel_ulong_t) (uintptr_t) (bogus_path1 + PATH1_SIZE),
174                         bogus_path1_after_addr },
175                 { (kernel_ulong_t) (uintptr_t) bogus_path1, bogus_path1_addr },
176                 { (kernel_ulong_t) (uintptr_t) bogus_path2, "\"" STR64 "\"" },
177         };
178
179         unsigned int i;
180         unsigned int j;
181         unsigned int k;
182         unsigned int l;
183         unsigned int m;
184         int rc;
185
186
187         snprintf(bogus_path1_addr, sizeof(bogus_path1_addr), "%p", bogus_path1);
188         snprintf(bogus_path1_after_addr, sizeof(bogus_path1_after_addr), "%p",
189                 bogus_path1 + PATH1_SIZE);
190
191         rc = fanotify_mark(-1, FAN_MARK_ADD, FAN_MODIFY | FAN_ONDIR,
192                                -100, ".");
193         printf("fanotify_mark(-1, %s, %s, %s, \".\") = %s\n",
194                str_fan_mark_add, str_fan_modify_ondir, str_at_fdcwd,
195                sprintrc(rc));
196
197         for (i = 0; i < ARRAY_SIZE(fds); i++) {
198                 for (j = 0; j < ARRAY_SIZE(flags); j++) {
199                         for (k = 0; k < ARRAY_SIZE(masks); k++) {
200                                 for (l = 0; l < ARRAY_SIZE(dirfds); l++) {
201                                         for (m = 0; m < ARRAY_SIZE(paths); m++)
202                                                 do_call(fds[i],
203                                                         flags[j].val,
204                                                         flags[j].str,
205                                                         masks[k].val,
206                                                         masks[k].str,
207                                                         dirfds[l].val,
208                                                         dirfds[l].str,
209                                                         paths[m].val,
210                                                         paths[m].str);
211                                 }
212                         }
213                 }
214         }
215
216         puts("+++ exited with 0 +++");
217         return 0;
218 }
219
220 #else
221
222 SKIP_MAIN_UNDEFINED("HAVE_SYS_FANOTIFY_H && HAVE_FANOTIFY_MARK && "
223                     "__NR_fanotify_mark")
224
225 #endif