1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) 2018 Matthew Bobrowski. All Rights Reserved.
4*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) Linux Test Project, 2020-2022
5*49cdfc7eSAndroid Build Coastguard Worker *
6*49cdfc7eSAndroid Build Coastguard Worker * Started by Matthew Bobrowski <[email protected]>
7*49cdfc7eSAndroid Build Coastguard Worker */
8*49cdfc7eSAndroid Build Coastguard Worker
9*49cdfc7eSAndroid Build Coastguard Worker /*\
10*49cdfc7eSAndroid Build Coastguard Worker * [Description]
11*49cdfc7eSAndroid Build Coastguard Worker * This test file has been designed to ensure that the fanotify
12*49cdfc7eSAndroid Build Coastguard Worker * system calls fanotify_init(2) and fanotify_mark(2) return the
13*49cdfc7eSAndroid Build Coastguard Worker * correct error code to the calling process when an invalid flag or
14*49cdfc7eSAndroid Build Coastguard Worker * mask value has been specified in conjunction with FAN_REPORT_FID.
15*49cdfc7eSAndroid Build Coastguard Worker */
16*49cdfc7eSAndroid Build Coastguard Worker
17*49cdfc7eSAndroid Build Coastguard Worker /*
18*49cdfc7eSAndroid Build Coastguard Worker * The ENOTDIR test cases are regression tests for commits:
19*49cdfc7eSAndroid Build Coastguard Worker *
20*49cdfc7eSAndroid Build Coastguard Worker * ceaf69f8eadc fanotify: do not allow setting dirent events in mask of non-dir
21*49cdfc7eSAndroid Build Coastguard Worker * 8698e3bab4dd fanotify: refine the validation checks on non-dir inode mask
22*49cdfc7eSAndroid Build Coastguard Worker *
23*49cdfc7eSAndroid Build Coastguard Worker * The pipes test cases are regression tests for commit:
24*49cdfc7eSAndroid Build Coastguard Worker * 69562eb0bd3e fanotify: disallow mount/sb marks on kernel internal pseudo fs
25*49cdfc7eSAndroid Build Coastguard Worker */
26*49cdfc7eSAndroid Build Coastguard Worker
27*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
28*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
29*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
30*49cdfc7eSAndroid Build Coastguard Worker
31*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_SYS_FANOTIFY_H
32*49cdfc7eSAndroid Build Coastguard Worker #include "fanotify.h"
33*49cdfc7eSAndroid Build Coastguard Worker
34*49cdfc7eSAndroid Build Coastguard Worker #define MNTPOINT "mntpoint"
35*49cdfc7eSAndroid Build Coastguard Worker #define FILE1 MNTPOINT"/file1"
36*49cdfc7eSAndroid Build Coastguard Worker
37*49cdfc7eSAndroid Build Coastguard Worker /*
38*49cdfc7eSAndroid Build Coastguard Worker * List of inode events that are only available when notification group is
39*49cdfc7eSAndroid Build Coastguard Worker * set to report fid.
40*49cdfc7eSAndroid Build Coastguard Worker */
41*49cdfc7eSAndroid Build Coastguard Worker #define INODE_EVENTS (FAN_ATTRIB | FAN_CREATE | FAN_DELETE | FAN_MOVE | \
42*49cdfc7eSAndroid Build Coastguard Worker FAN_DELETE_SELF | FAN_MOVE_SELF)
43*49cdfc7eSAndroid Build Coastguard Worker
44*49cdfc7eSAndroid Build Coastguard Worker #define FLAGS_DESC(flags) {(flags), (#flags)}
45*49cdfc7eSAndroid Build Coastguard Worker
46*49cdfc7eSAndroid Build Coastguard Worker static int pipes[2] = {-1, -1};
47*49cdfc7eSAndroid Build Coastguard Worker static int fanotify_fd;
48*49cdfc7eSAndroid Build Coastguard Worker static int ignore_mark_unsupported;
49*49cdfc7eSAndroid Build Coastguard Worker static int filesystem_mark_unsupported;
50*49cdfc7eSAndroid Build Coastguard Worker static int se_enforcing;
51*49cdfc7eSAndroid Build Coastguard Worker static unsigned int supported_init_flags;
52*49cdfc7eSAndroid Build Coastguard Worker
53*49cdfc7eSAndroid Build Coastguard Worker struct test_case_flags_t {
54*49cdfc7eSAndroid Build Coastguard Worker unsigned long long flags;
55*49cdfc7eSAndroid Build Coastguard Worker const char *desc;
56*49cdfc7eSAndroid Build Coastguard Worker };
57*49cdfc7eSAndroid Build Coastguard Worker
58*49cdfc7eSAndroid Build Coastguard Worker /*
59*49cdfc7eSAndroid Build Coastguard Worker * Each test case has been designed in a manner whereby the values defined
60*49cdfc7eSAndroid Build Coastguard Worker * within should result in the interface to return an error to the calling
61*49cdfc7eSAndroid Build Coastguard Worker * process.
62*49cdfc7eSAndroid Build Coastguard Worker */
63*49cdfc7eSAndroid Build Coastguard Worker static struct test_case_t {
64*49cdfc7eSAndroid Build Coastguard Worker struct test_case_flags_t init;
65*49cdfc7eSAndroid Build Coastguard Worker struct test_case_flags_t mark;
66*49cdfc7eSAndroid Build Coastguard Worker /* when mask.flags == 0, fanotify_init() is expected to fail */
67*49cdfc7eSAndroid Build Coastguard Worker struct test_case_flags_t mask;
68*49cdfc7eSAndroid Build Coastguard Worker int expected_errno;
69*49cdfc7eSAndroid Build Coastguard Worker int *pfd;
70*49cdfc7eSAndroid Build Coastguard Worker } test_cases[] = {
71*49cdfc7eSAndroid Build Coastguard Worker /* FAN_REPORT_FID without class FAN_CLASS_NOTIF is not valid */
72*49cdfc7eSAndroid Build Coastguard Worker {
73*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_CONTENT | FAN_REPORT_FID),
74*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = EINVAL,
75*49cdfc7eSAndroid Build Coastguard Worker },
76*49cdfc7eSAndroid Build Coastguard Worker
77*49cdfc7eSAndroid Build Coastguard Worker /* FAN_REPORT_FID without class FAN_CLASS_NOTIF is not valid */
78*49cdfc7eSAndroid Build Coastguard Worker {
79*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_PRE_CONTENT | FAN_REPORT_FID),
80*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = EINVAL,
81*49cdfc7eSAndroid Build Coastguard Worker },
82*49cdfc7eSAndroid Build Coastguard Worker
83*49cdfc7eSAndroid Build Coastguard Worker /* INODE_EVENTS in mask without class FAN_REPORT_FID are not valid */
84*49cdfc7eSAndroid Build Coastguard Worker {
85*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF),
86*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_INODE),
87*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(INODE_EVENTS),
88*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = EINVAL,
89*49cdfc7eSAndroid Build Coastguard Worker },
90*49cdfc7eSAndroid Build Coastguard Worker
91*49cdfc7eSAndroid Build Coastguard Worker /* INODE_EVENTS in mask with FAN_MARK_MOUNT are not valid */
92*49cdfc7eSAndroid Build Coastguard Worker {
93*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_FID),
94*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_MOUNT),
95*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(INODE_EVENTS),
96*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = EINVAL,
97*49cdfc7eSAndroid Build Coastguard Worker },
98*49cdfc7eSAndroid Build Coastguard Worker
99*49cdfc7eSAndroid Build Coastguard Worker /* FAN_REPORT_NAME without FAN_REPORT_DIR_FID is not valid */
100*49cdfc7eSAndroid Build Coastguard Worker {
101*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_NAME),
102*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = EINVAL,
103*49cdfc7eSAndroid Build Coastguard Worker },
104*49cdfc7eSAndroid Build Coastguard Worker
105*49cdfc7eSAndroid Build Coastguard Worker /* FAN_REPORT_NAME without FAN_REPORT_DIR_FID is not valid */
106*49cdfc7eSAndroid Build Coastguard Worker {
107*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_FID | FAN_REPORT_NAME),
108*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = EINVAL,
109*49cdfc7eSAndroid Build Coastguard Worker },
110*49cdfc7eSAndroid Build Coastguard Worker
111*49cdfc7eSAndroid Build Coastguard Worker /* FAN_REPORT_TARGET_FID without FAN_REPORT_FID is not valid */
112*49cdfc7eSAndroid Build Coastguard Worker {
113*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_TARGET_FID | FAN_REPORT_DFID_NAME),
114*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = EINVAL,
115*49cdfc7eSAndroid Build Coastguard Worker },
116*49cdfc7eSAndroid Build Coastguard Worker
117*49cdfc7eSAndroid Build Coastguard Worker /* FAN_REPORT_TARGET_FID without FAN_REPORT_NAME is not valid */
118*49cdfc7eSAndroid Build Coastguard Worker {
119*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_TARGET_FID | FAN_REPORT_DFID_FID),
120*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = EINVAL,
121*49cdfc7eSAndroid Build Coastguard Worker },
122*49cdfc7eSAndroid Build Coastguard Worker
123*49cdfc7eSAndroid Build Coastguard Worker /* FAN_RENAME without FAN_REPORT_NAME is not valid */
124*49cdfc7eSAndroid Build Coastguard Worker {
125*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_FID),
126*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_INODE),
127*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(FAN_RENAME),
128*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = EINVAL,
129*49cdfc7eSAndroid Build Coastguard Worker },
130*49cdfc7eSAndroid Build Coastguard Worker
131*49cdfc7eSAndroid Build Coastguard Worker /* With FAN_MARK_ONLYDIR on non-dir is not valid */
132*49cdfc7eSAndroid Build Coastguard Worker {
133*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF),
134*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_ONLYDIR),
135*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(FAN_OPEN),
136*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = ENOTDIR,
137*49cdfc7eSAndroid Build Coastguard Worker },
138*49cdfc7eSAndroid Build Coastguard Worker
139*49cdfc7eSAndroid Build Coastguard Worker /* With FAN_REPORT_TARGET_FID, FAN_DELETE on non-dir is not valid */
140*49cdfc7eSAndroid Build Coastguard Worker {
141*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME_TARGET),
142*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_INODE),
143*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(FAN_DELETE),
144*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = ENOTDIR,
145*49cdfc7eSAndroid Build Coastguard Worker },
146*49cdfc7eSAndroid Build Coastguard Worker
147*49cdfc7eSAndroid Build Coastguard Worker /* With FAN_REPORT_TARGET_FID, FAN_RENAME on non-dir is not valid */
148*49cdfc7eSAndroid Build Coastguard Worker {
149*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME_TARGET),
150*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_INODE),
151*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(FAN_RENAME),
152*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = ENOTDIR,
153*49cdfc7eSAndroid Build Coastguard Worker },
154*49cdfc7eSAndroid Build Coastguard Worker
155*49cdfc7eSAndroid Build Coastguard Worker /* With FAN_REPORT_TARGET_FID, FAN_ONDIR on non-dir is not valid */
156*49cdfc7eSAndroid Build Coastguard Worker {
157*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME_TARGET),
158*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_INODE),
159*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(FAN_OPEN | FAN_ONDIR),
160*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = ENOTDIR,
161*49cdfc7eSAndroid Build Coastguard Worker },
162*49cdfc7eSAndroid Build Coastguard Worker
163*49cdfc7eSAndroid Build Coastguard Worker /* With FAN_REPORT_TARGET_FID, FAN_EVENT_ON_CHILD on non-dir is not valid */
164*49cdfc7eSAndroid Build Coastguard Worker {
165*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME_TARGET),
166*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_INODE),
167*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(FAN_OPEN | FAN_EVENT_ON_CHILD),
168*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = ENOTDIR,
169*49cdfc7eSAndroid Build Coastguard Worker },
170*49cdfc7eSAndroid Build Coastguard Worker
171*49cdfc7eSAndroid Build Coastguard Worker /* FAN_MARK_IGNORE_SURV with FAN_DELETE on non-dir is not valid */
172*49cdfc7eSAndroid Build Coastguard Worker {
173*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME),
174*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_IGNORE_SURV),
175*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(FAN_DELETE),
176*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = ENOTDIR,
177*49cdfc7eSAndroid Build Coastguard Worker },
178*49cdfc7eSAndroid Build Coastguard Worker
179*49cdfc7eSAndroid Build Coastguard Worker /* FAN_MARK_IGNORE_SURV with FAN_RENAME on non-dir is not valid */
180*49cdfc7eSAndroid Build Coastguard Worker {
181*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME),
182*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_IGNORE_SURV),
183*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(FAN_RENAME),
184*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = ENOTDIR,
185*49cdfc7eSAndroid Build Coastguard Worker },
186*49cdfc7eSAndroid Build Coastguard Worker
187*49cdfc7eSAndroid Build Coastguard Worker /* FAN_MARK_IGNORE_SURV with FAN_ONDIR on non-dir is not valid */
188*49cdfc7eSAndroid Build Coastguard Worker {
189*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME),
190*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_IGNORE_SURV),
191*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(FAN_OPEN | FAN_ONDIR),
192*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = ENOTDIR,
193*49cdfc7eSAndroid Build Coastguard Worker },
194*49cdfc7eSAndroid Build Coastguard Worker
195*49cdfc7eSAndroid Build Coastguard Worker /* FAN_MARK_IGNORE_SURV with FAN_EVENT_ON_CHILD on non-dir is not valid */
196*49cdfc7eSAndroid Build Coastguard Worker {
197*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF | FAN_REPORT_DFID_NAME),
198*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_IGNORE_SURV),
199*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(FAN_OPEN | FAN_EVENT_ON_CHILD),
200*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = ENOTDIR,
201*49cdfc7eSAndroid Build Coastguard Worker },
202*49cdfc7eSAndroid Build Coastguard Worker
203*49cdfc7eSAndroid Build Coastguard Worker /* FAN_MARK_IGNORE without FAN_MARK_IGNORED_SURV_MODIFY on directory is not valid */
204*49cdfc7eSAndroid Build Coastguard Worker {
205*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF),
206*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_IGNORE),
207*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(FAN_OPEN),
208*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = EISDIR,
209*49cdfc7eSAndroid Build Coastguard Worker },
210*49cdfc7eSAndroid Build Coastguard Worker
211*49cdfc7eSAndroid Build Coastguard Worker /* FAN_MARK_IGNORE without FAN_MARK_IGNORED_SURV_MODIFY on mount mark is not valid */
212*49cdfc7eSAndroid Build Coastguard Worker {
213*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF),
214*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_MOUNT | FAN_MARK_IGNORE),
215*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(FAN_OPEN),
216*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = EINVAL,
217*49cdfc7eSAndroid Build Coastguard Worker },
218*49cdfc7eSAndroid Build Coastguard Worker
219*49cdfc7eSAndroid Build Coastguard Worker /* FAN_MARK_IGNORE without FAN_MARK_IGNORED_SURV_MODIFY on filesystem mark is not valid */
220*49cdfc7eSAndroid Build Coastguard Worker {
221*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF),
222*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_FILESYSTEM | FAN_MARK_IGNORE),
223*49cdfc7eSAndroid Build Coastguard Worker .mask = FLAGS_DESC(FAN_OPEN),
224*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = EINVAL,
225*49cdfc7eSAndroid Build Coastguard Worker },
226*49cdfc7eSAndroid Build Coastguard Worker /* mount mark on anonymous pipe is not valid */
227*49cdfc7eSAndroid Build Coastguard Worker {
228*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF),
229*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_MOUNT),
230*49cdfc7eSAndroid Build Coastguard Worker .mask = { FAN_ACCESS, "anonymous pipe"},
231*49cdfc7eSAndroid Build Coastguard Worker .pfd = pipes,
232*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = EINVAL,
233*49cdfc7eSAndroid Build Coastguard Worker },
234*49cdfc7eSAndroid Build Coastguard Worker /* filesystem mark on anonymous pipe is not valid */
235*49cdfc7eSAndroid Build Coastguard Worker {
236*49cdfc7eSAndroid Build Coastguard Worker .init = FLAGS_DESC(FAN_CLASS_NOTIF),
237*49cdfc7eSAndroid Build Coastguard Worker .mark = FLAGS_DESC(FAN_MARK_FILESYSTEM),
238*49cdfc7eSAndroid Build Coastguard Worker .mask = { FAN_ACCESS, "anonymous pipe"},
239*49cdfc7eSAndroid Build Coastguard Worker .pfd = pipes,
240*49cdfc7eSAndroid Build Coastguard Worker .expected_errno = EINVAL,
241*49cdfc7eSAndroid Build Coastguard Worker },
242*49cdfc7eSAndroid Build Coastguard Worker };
243*49cdfc7eSAndroid Build Coastguard Worker
do_test(unsigned int number)244*49cdfc7eSAndroid Build Coastguard Worker static void do_test(unsigned int number)
245*49cdfc7eSAndroid Build Coastguard Worker {
246*49cdfc7eSAndroid Build Coastguard Worker struct test_case_t *tc = &test_cases[number];
247*49cdfc7eSAndroid Build Coastguard Worker
248*49cdfc7eSAndroid Build Coastguard Worker tst_res(TINFO, "Test case %d: fanotify_init(%s, O_RDONLY)", number,
249*49cdfc7eSAndroid Build Coastguard Worker tc->init.desc);
250*49cdfc7eSAndroid Build Coastguard Worker
251*49cdfc7eSAndroid Build Coastguard Worker if (tc->init.flags & ~supported_init_flags) {
252*49cdfc7eSAndroid Build Coastguard Worker tst_res(TCONF, "Unsupported init flags");
253*49cdfc7eSAndroid Build Coastguard Worker return;
254*49cdfc7eSAndroid Build Coastguard Worker }
255*49cdfc7eSAndroid Build Coastguard Worker
256*49cdfc7eSAndroid Build Coastguard Worker if (ignore_mark_unsupported && tc->mark.flags & FAN_MARK_IGNORE) {
257*49cdfc7eSAndroid Build Coastguard Worker tst_res(TCONF, "FAN_MARK_IGNORE not supported in kernel?");
258*49cdfc7eSAndroid Build Coastguard Worker return;
259*49cdfc7eSAndroid Build Coastguard Worker }
260*49cdfc7eSAndroid Build Coastguard Worker
261*49cdfc7eSAndroid Build Coastguard Worker if (!tc->mask.flags && tc->expected_errno) {
262*49cdfc7eSAndroid Build Coastguard Worker TST_EXP_FAIL(fanotify_init(tc->init.flags, O_RDONLY),
263*49cdfc7eSAndroid Build Coastguard Worker tc->expected_errno);
264*49cdfc7eSAndroid Build Coastguard Worker } else {
265*49cdfc7eSAndroid Build Coastguard Worker TST_EXP_FD(fanotify_init(tc->init.flags, O_RDONLY));
266*49cdfc7eSAndroid Build Coastguard Worker }
267*49cdfc7eSAndroid Build Coastguard Worker
268*49cdfc7eSAndroid Build Coastguard Worker fanotify_fd = TST_RET;
269*49cdfc7eSAndroid Build Coastguard Worker
270*49cdfc7eSAndroid Build Coastguard Worker if (fanotify_fd < 0)
271*49cdfc7eSAndroid Build Coastguard Worker return;
272*49cdfc7eSAndroid Build Coastguard Worker
273*49cdfc7eSAndroid Build Coastguard Worker if (!tc->mask.flags)
274*49cdfc7eSAndroid Build Coastguard Worker goto out;
275*49cdfc7eSAndroid Build Coastguard Worker
276*49cdfc7eSAndroid Build Coastguard Worker /* Set mark on non-dir only when expecting error ENOTDIR */
277*49cdfc7eSAndroid Build Coastguard Worker const char *path = tc->expected_errno == ENOTDIR ? FILE1 : MNTPOINT;
278*49cdfc7eSAndroid Build Coastguard Worker const int exp_errs[] = {tc->expected_errno, EACCES};
279*49cdfc7eSAndroid Build Coastguard Worker int dirfd = AT_FDCWD;
280*49cdfc7eSAndroid Build Coastguard Worker
281*49cdfc7eSAndroid Build Coastguard Worker if (tc->pfd) {
282*49cdfc7eSAndroid Build Coastguard Worker dirfd = tc->pfd[0];
283*49cdfc7eSAndroid Build Coastguard Worker path = NULL;
284*49cdfc7eSAndroid Build Coastguard Worker }
285*49cdfc7eSAndroid Build Coastguard Worker
286*49cdfc7eSAndroid Build Coastguard Worker tst_res(TINFO, "Testing %s with %s",
287*49cdfc7eSAndroid Build Coastguard Worker tc->mark.desc, tc->mask.desc);
288*49cdfc7eSAndroid Build Coastguard Worker
289*49cdfc7eSAndroid Build Coastguard Worker TST_EXP_FAIL_ARR(fanotify_mark(fanotify_fd, FAN_MARK_ADD | tc->mark.flags,
290*49cdfc7eSAndroid Build Coastguard Worker tc->mask.flags, dirfd, path), exp_errs, se_enforcing ? 2 : 1);
291*49cdfc7eSAndroid Build Coastguard Worker
292*49cdfc7eSAndroid Build Coastguard Worker /*
293*49cdfc7eSAndroid Build Coastguard Worker * ENOTDIR are errors for events/flags not allowed on a non-dir inode.
294*49cdfc7eSAndroid Build Coastguard Worker * Try to set an inode mark on a directory and it should succeed.
295*49cdfc7eSAndroid Build Coastguard Worker * Try to set directory events in filesystem mark mask on non-dir
296*49cdfc7eSAndroid Build Coastguard Worker * and it should succeed.
297*49cdfc7eSAndroid Build Coastguard Worker */
298*49cdfc7eSAndroid Build Coastguard Worker if (TST_PASS && tc->expected_errno == ENOTDIR) {
299*49cdfc7eSAndroid Build Coastguard Worker SAFE_FANOTIFY_MARK(fanotify_fd, FAN_MARK_ADD | tc->mark.flags,
300*49cdfc7eSAndroid Build Coastguard Worker tc->mask.flags, AT_FDCWD, MNTPOINT);
301*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS,
302*49cdfc7eSAndroid Build Coastguard Worker "Adding an inode mark on directory did not fail with "
303*49cdfc7eSAndroid Build Coastguard Worker "ENOTDIR error as on non-dir inode");
304*49cdfc7eSAndroid Build Coastguard Worker
305*49cdfc7eSAndroid Build Coastguard Worker if (!(tc->mark.flags & FAN_MARK_ONLYDIR) && !filesystem_mark_unsupported) {
306*49cdfc7eSAndroid Build Coastguard Worker SAFE_FANOTIFY_MARK(fanotify_fd, FAN_MARK_ADD | tc->mark.flags |
307*49cdfc7eSAndroid Build Coastguard Worker FAN_MARK_FILESYSTEM, tc->mask.flags,
308*49cdfc7eSAndroid Build Coastguard Worker AT_FDCWD, FILE1);
309*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS,
310*49cdfc7eSAndroid Build Coastguard Worker "Adding a filesystem mark on non-dir did not fail with "
311*49cdfc7eSAndroid Build Coastguard Worker "ENOTDIR error as with an inode mark");
312*49cdfc7eSAndroid Build Coastguard Worker }
313*49cdfc7eSAndroid Build Coastguard Worker }
314*49cdfc7eSAndroid Build Coastguard Worker
315*49cdfc7eSAndroid Build Coastguard Worker out:
316*49cdfc7eSAndroid Build Coastguard Worker if (fanotify_fd > 0)
317*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(fanotify_fd);
318*49cdfc7eSAndroid Build Coastguard Worker }
319*49cdfc7eSAndroid Build Coastguard Worker
do_setup(void)320*49cdfc7eSAndroid Build Coastguard Worker static void do_setup(void)
321*49cdfc7eSAndroid Build Coastguard Worker {
322*49cdfc7eSAndroid Build Coastguard Worker unsigned int all_init_flags = FAN_REPORT_DFID_NAME_TARGET |
323*49cdfc7eSAndroid Build Coastguard Worker FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | FAN_CLASS_PRE_CONTENT;
324*49cdfc7eSAndroid Build Coastguard Worker
325*49cdfc7eSAndroid Build Coastguard Worker /* Require FAN_REPORT_FID support for all tests to simplify per test case requirements */
326*49cdfc7eSAndroid Build Coastguard Worker REQUIRE_FANOTIFY_INIT_FLAGS_SUPPORTED_ON_FS(FAN_REPORT_FID, MNTPOINT);
327*49cdfc7eSAndroid Build Coastguard Worker supported_init_flags = fanotify_get_supported_init_flags(all_init_flags, MNTPOINT);
328*49cdfc7eSAndroid Build Coastguard Worker
329*49cdfc7eSAndroid Build Coastguard Worker ignore_mark_unsupported = fanotify_mark_supported_on_fs(FAN_MARK_IGNORE_SURV,
330*49cdfc7eSAndroid Build Coastguard Worker MNTPOINT);
331*49cdfc7eSAndroid Build Coastguard Worker filesystem_mark_unsupported =
332*49cdfc7eSAndroid Build Coastguard Worker fanotify_flags_supported_on_fs(FAN_REPORT_FID, FAN_MARK_FILESYSTEM, FAN_OPEN,
333*49cdfc7eSAndroid Build Coastguard Worker MNTPOINT);
334*49cdfc7eSAndroid Build Coastguard Worker
335*49cdfc7eSAndroid Build Coastguard Worker /* Create temporary test file to place marks on */
336*49cdfc7eSAndroid Build Coastguard Worker SAFE_FILE_PRINTF(FILE1, "0");
337*49cdfc7eSAndroid Build Coastguard Worker /* Create anonymous pipes to place marks on */
338*49cdfc7eSAndroid Build Coastguard Worker SAFE_PIPE2(pipes, O_CLOEXEC);
339*49cdfc7eSAndroid Build Coastguard Worker
340*49cdfc7eSAndroid Build Coastguard Worker se_enforcing = tst_selinux_enforcing();
341*49cdfc7eSAndroid Build Coastguard Worker }
342*49cdfc7eSAndroid Build Coastguard Worker
do_cleanup(void)343*49cdfc7eSAndroid Build Coastguard Worker static void do_cleanup(void)
344*49cdfc7eSAndroid Build Coastguard Worker {
345*49cdfc7eSAndroid Build Coastguard Worker if (fanotify_fd > 0)
346*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(fanotify_fd);
347*49cdfc7eSAndroid Build Coastguard Worker if (pipes[0] != -1)
348*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(pipes[0]);
349*49cdfc7eSAndroid Build Coastguard Worker if (pipes[1] != -1)
350*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(pipes[1]);
351*49cdfc7eSAndroid Build Coastguard Worker }
352*49cdfc7eSAndroid Build Coastguard Worker
353*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
354*49cdfc7eSAndroid Build Coastguard Worker .needs_root = 1,
355*49cdfc7eSAndroid Build Coastguard Worker .test = do_test,
356*49cdfc7eSAndroid Build Coastguard Worker .tcnt = ARRAY_SIZE(test_cases),
357*49cdfc7eSAndroid Build Coastguard Worker .setup = do_setup,
358*49cdfc7eSAndroid Build Coastguard Worker .cleanup = do_cleanup,
359*49cdfc7eSAndroid Build Coastguard Worker .mount_device = 1,
360*49cdfc7eSAndroid Build Coastguard Worker .mntpoint = MNTPOINT,
361*49cdfc7eSAndroid Build Coastguard Worker .all_filesystems = 1,
362*49cdfc7eSAndroid Build Coastguard Worker .tags = (const struct tst_tag[]) {
363*49cdfc7eSAndroid Build Coastguard Worker {"linux-git", "ceaf69f8eadc"},
364*49cdfc7eSAndroid Build Coastguard Worker {"linux-git", "8698e3bab4dd"},
365*49cdfc7eSAndroid Build Coastguard Worker {"linux-git", "69562eb0bd3e"},
366*49cdfc7eSAndroid Build Coastguard Worker {}
367*49cdfc7eSAndroid Build Coastguard Worker }
368*49cdfc7eSAndroid Build Coastguard Worker };
369*49cdfc7eSAndroid Build Coastguard Worker
370*49cdfc7eSAndroid Build Coastguard Worker #else
371*49cdfc7eSAndroid Build Coastguard Worker TST_TEST_TCONF("System does not have required fanotify support");
372*49cdfc7eSAndroid Build Coastguard Worker #endif
373