hc
2024-05-11 04dd17822334871b23ea2862f7798fb0e0007777
kernel/fs/notify/fanotify/fanotify_user.c
....@@ -17,6 +17,8 @@
1717 #include <linux/compat.h>
1818 #include <linux/sched/signal.h>
1919 #include <linux/memcontrol.h>
20
+#include <linux/statfs.h>
21
+#include <linux/exportfs.h>
2022
2123 #include <asm/ioctls.h>
2224
....@@ -44,42 +46,90 @@
4446 extern const struct fsnotify_ops fanotify_fsnotify_ops;
4547
4648 struct kmem_cache *fanotify_mark_cache __read_mostly;
47
-struct kmem_cache *fanotify_event_cachep __read_mostly;
49
+struct kmem_cache *fanotify_fid_event_cachep __read_mostly;
50
+struct kmem_cache *fanotify_path_event_cachep __read_mostly;
4851 struct kmem_cache *fanotify_perm_event_cachep __read_mostly;
4952
53
+#define FANOTIFY_EVENT_ALIGN 4
54
+#define FANOTIFY_INFO_HDR_LEN \
55
+ (sizeof(struct fanotify_event_info_fid) + sizeof(struct file_handle))
56
+
57
+static int fanotify_fid_info_len(int fh_len, int name_len)
58
+{
59
+ int info_len = fh_len;
60
+
61
+ if (name_len)
62
+ info_len += name_len + 1;
63
+
64
+ return roundup(FANOTIFY_INFO_HDR_LEN + info_len, FANOTIFY_EVENT_ALIGN);
65
+}
66
+
67
+static int fanotify_event_info_len(unsigned int fid_mode,
68
+ struct fanotify_event *event)
69
+{
70
+ struct fanotify_info *info = fanotify_event_info(event);
71
+ int dir_fh_len = fanotify_event_dir_fh_len(event);
72
+ int fh_len = fanotify_event_object_fh_len(event);
73
+ int info_len = 0;
74
+ int dot_len = 0;
75
+
76
+ if (dir_fh_len) {
77
+ info_len += fanotify_fid_info_len(dir_fh_len, info->name_len);
78
+ } else if ((fid_mode & FAN_REPORT_NAME) && (event->mask & FAN_ONDIR)) {
79
+ /*
80
+ * With group flag FAN_REPORT_NAME, if name was not recorded in
81
+ * event on a directory, we will report the name ".".
82
+ */
83
+ dot_len = 1;
84
+ }
85
+
86
+ if (fh_len)
87
+ info_len += fanotify_fid_info_len(fh_len, dot_len);
88
+
89
+ return info_len;
90
+}
91
+
5092 /*
51
- * Get an fsnotify notification event if one exists and is small
93
+ * Get an fanotify notification event if one exists and is small
5294 * enough to fit in "count". Return an error pointer if the count
53
- * is not large enough.
54
- *
55
- * Called with the group->notification_lock held.
95
+ * is not large enough. When permission event is dequeued, its state is
96
+ * updated accordingly.
5697 */
57
-static struct fsnotify_event *get_one_event(struct fsnotify_group *group,
98
+static struct fanotify_event *get_one_event(struct fsnotify_group *group,
5899 size_t count)
59100 {
60
- assert_spin_locked(&group->notification_lock);
101
+ size_t event_size = FAN_EVENT_METADATA_LEN;
102
+ struct fanotify_event *event = NULL;
103
+ unsigned int fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS);
61104
62105 pr_debug("%s: group=%p count=%zd\n", __func__, group, count);
63106
107
+ spin_lock(&group->notification_lock);
64108 if (fsnotify_notify_queue_is_empty(group))
65
- return NULL;
109
+ goto out;
66110
67
- if (FAN_EVENT_METADATA_LEN > count)
68
- return ERR_PTR(-EINVAL);
111
+ if (fid_mode) {
112
+ event_size += fanotify_event_info_len(fid_mode,
113
+ FANOTIFY_E(fsnotify_peek_first_event(group)));
114
+ }
69115
70
- /* held the notification_lock the whole time, so this is the
71
- * same event we peeked above */
72
- return fsnotify_remove_first_event(group);
116
+ if (event_size > count) {
117
+ event = ERR_PTR(-EINVAL);
118
+ goto out;
119
+ }
120
+ event = FANOTIFY_E(fsnotify_remove_first_event(group));
121
+ if (fanotify_is_perm_event(event->mask))
122
+ FANOTIFY_PERM(event)->state = FAN_EVENT_REPORTED;
123
+out:
124
+ spin_unlock(&group->notification_lock);
125
+ return event;
73126 }
74127
75
-static int create_fd(struct fsnotify_group *group,
76
- struct fanotify_event_info *event,
128
+static int create_fd(struct fsnotify_group *group, struct path *path,
77129 struct file **file)
78130 {
79131 int client_fd;
80132 struct file *new_file;
81
-
82
- pr_debug("%s: group=%p event=%p\n", __func__, group, event);
83133
84134 client_fd = get_unused_fd_flags(group->fanotify_data.f_flags);
85135 if (client_fd < 0)
....@@ -89,14 +139,9 @@
89139 * we need a new file handle for the userspace program so it can read even if it was
90140 * originally opened O_WRONLY.
91141 */
92
- /* it's possible this event was an overflow event. in that case dentry and mnt
93
- * are NULL; That's fine, just don't call dentry open */
94
- if (event->path.dentry && event->path.mnt)
95
- new_file = dentry_open(&event->path,
96
- group->fanotify_data.f_flags | FMODE_NONOTIFY,
97
- current_cred());
98
- else
99
- new_file = ERR_PTR(-EOVERFLOW);
142
+ new_file = dentry_open(path,
143
+ group->fanotify_data.f_flags | FMODE_NONOTIFY,
144
+ current_cred());
100145 if (IS_ERR(new_file)) {
101146 /*
102147 * we still send an event even if we can't open the file. this
....@@ -114,62 +159,32 @@
114159 return client_fd;
115160 }
116161
117
-static int fill_event_metadata(struct fsnotify_group *group,
118
- struct fanotify_event_metadata *metadata,
119
- struct fsnotify_event *fsn_event,
120
- struct file **file)
162
+/*
163
+ * Finish processing of permission event by setting it to ANSWERED state and
164
+ * drop group->notification_lock.
165
+ */
166
+static void finish_permission_event(struct fsnotify_group *group,
167
+ struct fanotify_perm_event *event,
168
+ unsigned int response)
169
+ __releases(&group->notification_lock)
121170 {
122
- int ret = 0;
123
- struct fanotify_event_info *event;
171
+ bool destroy = false;
124172
125
- pr_debug("%s: group=%p metadata=%p event=%p\n", __func__,
126
- group, metadata, fsn_event);
127
-
128
- *file = NULL;
129
- event = container_of(fsn_event, struct fanotify_event_info, fse);
130
- metadata->event_len = FAN_EVENT_METADATA_LEN;
131
- metadata->metadata_len = FAN_EVENT_METADATA_LEN;
132
- metadata->vers = FANOTIFY_METADATA_VERSION;
133
- metadata->reserved = 0;
134
- metadata->mask = fsn_event->mask & FAN_ALL_OUTGOING_EVENTS;
135
- metadata->pid = pid_vnr(event->tgid);
136
- if (unlikely(fsn_event->mask & FAN_Q_OVERFLOW))
137
- metadata->fd = FAN_NOFD;
138
- else {
139
- metadata->fd = create_fd(group, event, file);
140
- if (metadata->fd < 0)
141
- ret = metadata->fd;
142
- }
143
-
144
- return ret;
145
-}
146
-
147
-static struct fanotify_perm_event_info *dequeue_event(
148
- struct fsnotify_group *group, int fd)
149
-{
150
- struct fanotify_perm_event_info *event, *return_e = NULL;
151
-
152
- spin_lock(&group->notification_lock);
153
- list_for_each_entry(event, &group->fanotify_data.access_list,
154
- fae.fse.list) {
155
- if (event->fd != fd)
156
- continue;
157
-
158
- list_del_init(&event->fae.fse.list);
159
- return_e = event;
160
- break;
161
- }
173
+ assert_spin_locked(&group->notification_lock);
174
+ event->response = response;
175
+ if (event->state == FAN_EVENT_CANCELED)
176
+ destroy = true;
177
+ else
178
+ event->state = FAN_EVENT_ANSWERED;
162179 spin_unlock(&group->notification_lock);
163
-
164
- pr_debug("%s: found return_re=%p\n", __func__, return_e);
165
-
166
- return return_e;
180
+ if (destroy)
181
+ fsnotify_destroy_event(group, &event->fae.fse);
167182 }
168183
169184 static int process_access_response(struct fsnotify_group *group,
170185 struct fanotify_response *response_struct)
171186 {
172
- struct fanotify_perm_event_info *event;
187
+ struct fanotify_perm_event *event;
173188 int fd = response_struct->fd;
174189 int response = response_struct->response;
175190
....@@ -191,45 +206,233 @@
191206 if (fd < 0)
192207 return -EINVAL;
193208
194
- if ((response & FAN_AUDIT) && !group->fanotify_data.audit)
209
+ if ((response & FAN_AUDIT) && !FAN_GROUP_FLAG(group, FAN_ENABLE_AUDIT))
195210 return -EINVAL;
196211
197
- event = dequeue_event(group, fd);
198
- if (!event)
199
- return -ENOENT;
212
+ spin_lock(&group->notification_lock);
213
+ list_for_each_entry(event, &group->fanotify_data.access_list,
214
+ fae.fse.list) {
215
+ if (event->fd != fd)
216
+ continue;
200217
201
- event->response = response;
202
- wake_up(&group->fanotify_data.access_waitq);
218
+ list_del_init(&event->fae.fse.list);
219
+ finish_permission_event(group, event, response);
220
+ wake_up(&group->fanotify_data.access_waitq);
221
+ return 0;
222
+ }
223
+ spin_unlock(&group->notification_lock);
203224
204
- return 0;
225
+ return -ENOENT;
226
+}
227
+
228
+static int copy_info_to_user(__kernel_fsid_t *fsid, struct fanotify_fh *fh,
229
+ int info_type, const char *name, size_t name_len,
230
+ char __user *buf, size_t count)
231
+{
232
+ struct fanotify_event_info_fid info = { };
233
+ struct file_handle handle = { };
234
+ unsigned char bounce[FANOTIFY_INLINE_FH_LEN], *fh_buf;
235
+ size_t fh_len = fh ? fh->len : 0;
236
+ size_t info_len = fanotify_fid_info_len(fh_len, name_len);
237
+ size_t len = info_len;
238
+
239
+ pr_debug("%s: fh_len=%zu name_len=%zu, info_len=%zu, count=%zu\n",
240
+ __func__, fh_len, name_len, info_len, count);
241
+
242
+ if (!fh_len)
243
+ return 0;
244
+
245
+ if (WARN_ON_ONCE(len < sizeof(info) || len > count))
246
+ return -EFAULT;
247
+
248
+ /*
249
+ * Copy event info fid header followed by variable sized file handle
250
+ * and optionally followed by variable sized filename.
251
+ */
252
+ switch (info_type) {
253
+ case FAN_EVENT_INFO_TYPE_FID:
254
+ case FAN_EVENT_INFO_TYPE_DFID:
255
+ if (WARN_ON_ONCE(name_len))
256
+ return -EFAULT;
257
+ break;
258
+ case FAN_EVENT_INFO_TYPE_DFID_NAME:
259
+ if (WARN_ON_ONCE(!name || !name_len))
260
+ return -EFAULT;
261
+ break;
262
+ default:
263
+ return -EFAULT;
264
+ }
265
+
266
+ info.hdr.info_type = info_type;
267
+ info.hdr.len = len;
268
+ info.fsid = *fsid;
269
+ if (copy_to_user(buf, &info, sizeof(info)))
270
+ return -EFAULT;
271
+
272
+ buf += sizeof(info);
273
+ len -= sizeof(info);
274
+ if (WARN_ON_ONCE(len < sizeof(handle)))
275
+ return -EFAULT;
276
+
277
+ handle.handle_type = fh->type;
278
+ handle.handle_bytes = fh_len;
279
+ if (copy_to_user(buf, &handle, sizeof(handle)))
280
+ return -EFAULT;
281
+
282
+ buf += sizeof(handle);
283
+ len -= sizeof(handle);
284
+ if (WARN_ON_ONCE(len < fh_len))
285
+ return -EFAULT;
286
+
287
+ /*
288
+ * For an inline fh and inline file name, copy through stack to exclude
289
+ * the copy from usercopy hardening protections.
290
+ */
291
+ fh_buf = fanotify_fh_buf(fh);
292
+ if (fh_len <= FANOTIFY_INLINE_FH_LEN) {
293
+ memcpy(bounce, fh_buf, fh_len);
294
+ fh_buf = bounce;
295
+ }
296
+ if (copy_to_user(buf, fh_buf, fh_len))
297
+ return -EFAULT;
298
+
299
+ buf += fh_len;
300
+ len -= fh_len;
301
+
302
+ if (name_len) {
303
+ /* Copy the filename with terminating null */
304
+ name_len++;
305
+ if (WARN_ON_ONCE(len < name_len))
306
+ return -EFAULT;
307
+
308
+ if (copy_to_user(buf, name, name_len))
309
+ return -EFAULT;
310
+
311
+ buf += name_len;
312
+ len -= name_len;
313
+ }
314
+
315
+ /* Pad with 0's */
316
+ WARN_ON_ONCE(len < 0 || len >= FANOTIFY_EVENT_ALIGN);
317
+ if (len > 0 && clear_user(buf, len))
318
+ return -EFAULT;
319
+
320
+ return info_len;
205321 }
206322
207323 static ssize_t copy_event_to_user(struct fsnotify_group *group,
208
- struct fsnotify_event *event,
209
- char __user *buf)
324
+ struct fanotify_event *event,
325
+ char __user *buf, size_t count)
210326 {
211
- struct fanotify_event_metadata fanotify_event_metadata;
212
- struct file *f;
213
- int fd, ret;
327
+ struct fanotify_event_metadata metadata;
328
+ struct path *path = fanotify_event_path(event);
329
+ struct fanotify_info *info = fanotify_event_info(event);
330
+ unsigned int fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS);
331
+ struct file *f = NULL;
332
+ int ret, fd = FAN_NOFD;
333
+ int info_type = 0;
214334
215335 pr_debug("%s: group=%p event=%p\n", __func__, group, event);
216336
217
- ret = fill_event_metadata(group, &fanotify_event_metadata, event, &f);
218
- if (ret < 0)
219
- return ret;
337
+ metadata.event_len = FAN_EVENT_METADATA_LEN +
338
+ fanotify_event_info_len(fid_mode, event);
339
+ metadata.metadata_len = FAN_EVENT_METADATA_LEN;
340
+ metadata.vers = FANOTIFY_METADATA_VERSION;
341
+ metadata.reserved = 0;
342
+ metadata.mask = event->mask & FANOTIFY_OUTGOING_EVENTS;
343
+ metadata.pid = pid_vnr(event->pid);
220344
221
- fd = fanotify_event_metadata.fd;
345
+ if (path && path->mnt && path->dentry) {
346
+ fd = create_fd(group, path, &f);
347
+ if (fd < 0)
348
+ return fd;
349
+ }
350
+ metadata.fd = fd;
351
+
222352 ret = -EFAULT;
223
- if (copy_to_user(buf, &fanotify_event_metadata,
224
- fanotify_event_metadata.event_len))
353
+ /*
354
+ * Sanity check copy size in case get_one_event() and
355
+ * event_len sizes ever get out of sync.
356
+ */
357
+ if (WARN_ON_ONCE(metadata.event_len > count))
225358 goto out_close_fd;
226359
227
- if (fanotify_is_perm_event(event->mask))
228
- FANOTIFY_PE(event)->fd = fd;
360
+ if (copy_to_user(buf, &metadata, FAN_EVENT_METADATA_LEN))
361
+ goto out_close_fd;
229362
230
- if (fd != FAN_NOFD)
363
+ buf += FAN_EVENT_METADATA_LEN;
364
+ count -= FAN_EVENT_METADATA_LEN;
365
+
366
+ if (fanotify_is_perm_event(event->mask))
367
+ FANOTIFY_PERM(event)->fd = fd;
368
+
369
+ /* Event info records order is: dir fid + name, child fid */
370
+ if (fanotify_event_dir_fh_len(event)) {
371
+ info_type = info->name_len ? FAN_EVENT_INFO_TYPE_DFID_NAME :
372
+ FAN_EVENT_INFO_TYPE_DFID;
373
+ ret = copy_info_to_user(fanotify_event_fsid(event),
374
+ fanotify_info_dir_fh(info),
375
+ info_type, fanotify_info_name(info),
376
+ info->name_len, buf, count);
377
+ if (ret < 0)
378
+ goto out_close_fd;
379
+
380
+ buf += ret;
381
+ count -= ret;
382
+ }
383
+
384
+ if (fanotify_event_object_fh_len(event)) {
385
+ const char *dot = NULL;
386
+ int dot_len = 0;
387
+
388
+ if (fid_mode == FAN_REPORT_FID || info_type) {
389
+ /*
390
+ * With only group flag FAN_REPORT_FID only type FID is
391
+ * reported. Second info record type is always FID.
392
+ */
393
+ info_type = FAN_EVENT_INFO_TYPE_FID;
394
+ } else if ((fid_mode & FAN_REPORT_NAME) &&
395
+ (event->mask & FAN_ONDIR)) {
396
+ /*
397
+ * With group flag FAN_REPORT_NAME, if name was not
398
+ * recorded in an event on a directory, report the
399
+ * name "." with info type DFID_NAME.
400
+ */
401
+ info_type = FAN_EVENT_INFO_TYPE_DFID_NAME;
402
+ dot = ".";
403
+ dot_len = 1;
404
+ } else if ((event->mask & ALL_FSNOTIFY_DIRENT_EVENTS) ||
405
+ (event->mask & FAN_ONDIR)) {
406
+ /*
407
+ * With group flag FAN_REPORT_DIR_FID, a single info
408
+ * record has type DFID for directory entry modification
409
+ * event and for event on a directory.
410
+ */
411
+ info_type = FAN_EVENT_INFO_TYPE_DFID;
412
+ } else {
413
+ /*
414
+ * With group flags FAN_REPORT_DIR_FID|FAN_REPORT_FID,
415
+ * a single info record has type FID for event on a
416
+ * non-directory, when there is no directory to report.
417
+ * For example, on FAN_DELETE_SELF event.
418
+ */
419
+ info_type = FAN_EVENT_INFO_TYPE_FID;
420
+ }
421
+
422
+ ret = copy_info_to_user(fanotify_event_fsid(event),
423
+ fanotify_event_object_fh(event),
424
+ info_type, dot, dot_len, buf, count);
425
+ if (ret < 0)
426
+ goto out_close_fd;
427
+
428
+ buf += ret;
429
+ count -= ret;
430
+ }
431
+
432
+ if (f)
231433 fd_install(fd, f);
232
- return fanotify_event_metadata.event_len;
434
+
435
+ return metadata.event_len;
233436
234437 out_close_fd:
235438 if (fd != FAN_NOFD) {
....@@ -258,7 +461,7 @@
258461 size_t count, loff_t *pos)
259462 {
260463 struct fsnotify_group *group;
261
- struct fsnotify_event *kevent;
464
+ struct fanotify_event *event;
262465 char __user *start;
263466 int ret;
264467 DEFINE_WAIT_FUNC(wait, woken_wake_function);
....@@ -270,16 +473,18 @@
270473
271474 add_wait_queue(&group->notification_waitq, &wait);
272475 while (1) {
273
- spin_lock(&group->notification_lock);
274
- kevent = get_one_event(group, count);
275
- spin_unlock(&group->notification_lock);
276
-
277
- if (IS_ERR(kevent)) {
278
- ret = PTR_ERR(kevent);
476
+ /*
477
+ * User can supply arbitrarily large buffer. Avoid softlockups
478
+ * in case there are lots of available events.
479
+ */
480
+ cond_resched();
481
+ event = get_one_event(group, count);
482
+ if (IS_ERR(event)) {
483
+ ret = PTR_ERR(event);
279484 break;
280485 }
281486
282
- if (!kevent) {
487
+ if (!event) {
283488 ret = -EAGAIN;
284489 if (file->f_flags & O_NONBLOCK)
285490 break;
....@@ -295,7 +500,7 @@
295500 continue;
296501 }
297502
298
- ret = copy_event_to_user(group, kevent, buf);
503
+ ret = copy_event_to_user(group, event, buf, count);
299504 if (unlikely(ret == -EOPENSTALE)) {
300505 /*
301506 * We cannot report events with stale fd so drop it.
....@@ -310,15 +515,17 @@
310515 * Permission events get queued to wait for response. Other
311516 * events can be destroyed now.
312517 */
313
- if (!fanotify_is_perm_event(kevent->mask)) {
314
- fsnotify_destroy_event(group, kevent);
518
+ if (!fanotify_is_perm_event(event->mask)) {
519
+ fsnotify_destroy_event(group, &event->fse);
315520 } else {
316521 if (ret <= 0) {
317
- FANOTIFY_PE(kevent)->response = FAN_DENY;
522
+ spin_lock(&group->notification_lock);
523
+ finish_permission_event(group,
524
+ FANOTIFY_PERM(event), FAN_DENY);
318525 wake_up(&group->fanotify_data.access_waitq);
319526 } else {
320527 spin_lock(&group->notification_lock);
321
- list_add_tail(&kevent->list,
528
+ list_add_tail(&event->fse.list,
322529 &group->fanotify_data.access_list);
323530 spin_unlock(&group->notification_lock);
324531 }
....@@ -346,8 +553,10 @@
346553
347554 group = file->private_data;
348555
349
- if (count > sizeof(response))
350
- count = sizeof(response);
556
+ if (count < sizeof(response))
557
+ return -EINVAL;
558
+
559
+ count = sizeof(response);
351560
352561 pr_debug("%s: group=%p count=%zu\n", __func__, group, count);
353562
....@@ -364,8 +573,6 @@
364573 static int fanotify_release(struct inode *ignored, struct file *file)
365574 {
366575 struct fsnotify_group *group = file->private_data;
367
- struct fanotify_perm_event_info *event, *next;
368
- struct fsnotify_event *fsn_event;
369576
370577 /*
371578 * Stop new events from arriving in the notification queue. since
....@@ -379,13 +586,14 @@
379586 * and simulate reply from userspace.
380587 */
381588 spin_lock(&group->notification_lock);
382
- list_for_each_entry_safe(event, next, &group->fanotify_data.access_list,
383
- fae.fse.list) {
384
- pr_debug("%s: found group=%p event=%p\n", __func__, group,
385
- event);
589
+ while (!list_empty(&group->fanotify_data.access_list)) {
590
+ struct fanotify_perm_event *event;
386591
592
+ event = list_first_entry(&group->fanotify_data.access_list,
593
+ struct fanotify_perm_event, fae.fse.list);
387594 list_del_init(&event->fae.fse.list);
388
- event->response = FAN_ALLOW;
595
+ finish_permission_event(group, event, FAN_ALLOW);
596
+ spin_lock(&group->notification_lock);
389597 }
390598
391599 /*
....@@ -394,14 +602,17 @@
394602 * response is consumed and fanotify_get_response() returns.
395603 */
396604 while (!fsnotify_notify_queue_is_empty(group)) {
397
- fsn_event = fsnotify_remove_first_event(group);
398
- if (!(fsn_event->mask & FAN_ALL_PERM_EVENTS)) {
605
+ struct fanotify_event *event;
606
+
607
+ event = FANOTIFY_E(fsnotify_remove_first_event(group));
608
+ if (!(event->mask & FANOTIFY_PERM_EVENTS)) {
399609 spin_unlock(&group->notification_lock);
400
- fsnotify_destroy_event(group, fsn_event);
401
- spin_lock(&group->notification_lock);
610
+ fsnotify_destroy_event(group, &event->fse);
402611 } else {
403
- FANOTIFY_PE(fsn_event)->response = FAN_ALLOW;
612
+ finish_permission_event(group, FANOTIFY_PERM(event),
613
+ FAN_ALLOW);
404614 }
615
+ spin_lock(&group->notification_lock);
405616 }
406617 spin_unlock(&group->notification_lock);
407618
....@@ -447,12 +658,13 @@
447658 .fasync = NULL,
448659 .release = fanotify_release,
449660 .unlocked_ioctl = fanotify_ioctl,
450
- .compat_ioctl = fanotify_ioctl,
661
+ .compat_ioctl = compat_ptr_ioctl,
451662 .llseek = noop_llseek,
452663 };
453664
454665 static int fanotify_find_path(int dfd, const char __user *filename,
455
- struct path *path, unsigned int flags)
666
+ struct path *path, unsigned int flags, __u64 mask,
667
+ unsigned int obj_type)
456668 {
457669 int ret;
458670
....@@ -490,36 +702,42 @@
490702 }
491703
492704 /* you can only watch an inode if you have read permissions on it */
493
- ret = inode_permission2(path->mnt, path->dentry->d_inode, MAY_READ);
705
+ ret = inode_permission(path->dentry->d_inode, MAY_READ);
706
+ if (ret) {
707
+ path_put(path);
708
+ goto out;
709
+ }
710
+
711
+ ret = security_path_notify(path, mask, obj_type);
494712 if (ret)
495713 path_put(path);
714
+
496715 out:
497716 return ret;
498717 }
499718
500719 static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
501
- __u32 mask,
502
- unsigned int flags,
503
- int *destroy)
720
+ __u32 mask, unsigned int flags,
721
+ __u32 umask, int *destroy)
504722 {
505723 __u32 oldmask = 0;
506724
725
+ /* umask bits cannot be removed by user */
726
+ mask &= ~umask;
507727 spin_lock(&fsn_mark->lock);
508728 if (!(flags & FAN_MARK_IGNORED_MASK)) {
509
- __u32 tmask = fsn_mark->mask & ~mask;
510
-
511
- if (flags & FAN_MARK_ONDIR)
512
- tmask &= ~FAN_ONDIR;
513
-
514729 oldmask = fsn_mark->mask;
515
- fsn_mark->mask = tmask;
730
+ fsn_mark->mask &= ~mask;
516731 } else {
517
- __u32 tmask = fsn_mark->ignored_mask & ~mask;
518
- if (flags & FAN_MARK_ONDIR)
519
- tmask &= ~FAN_ONDIR;
520
- fsn_mark->ignored_mask = tmask;
732
+ fsn_mark->ignored_mask &= ~mask;
521733 }
522
- *destroy = !(fsn_mark->mask | fsn_mark->ignored_mask);
734
+ /*
735
+ * We need to keep the mark around even if remaining mask cannot
736
+ * result in any events (e.g. mask == FAN_ONDIR) to support incremenal
737
+ * changes to the mask.
738
+ * Destroy mark when only umask bits remain.
739
+ */
740
+ *destroy = !((fsn_mark->mask | fsn_mark->ignored_mask) & ~umask);
523741 spin_unlock(&fsn_mark->lock);
524742
525743 return mask & oldmask;
....@@ -527,7 +745,7 @@
527745
528746 static int fanotify_remove_mark(struct fsnotify_group *group,
529747 fsnotify_connp_t *connp, __u32 mask,
530
- unsigned int flags)
748
+ unsigned int flags, __u32 umask)
531749 {
532750 struct fsnotify_mark *fsn_mark = NULL;
533751 __u32 removed;
....@@ -541,7 +759,7 @@
541759 }
542760
543761 removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags,
544
- &destroy_mark);
762
+ umask, &destroy_mark);
545763 if (removed & fsnotify_conn_mask(fsn_mark->connector))
546764 fsnotify_recalc_mask(fsn_mark->connector);
547765 if (destroy_mark)
....@@ -557,18 +775,26 @@
557775
558776 static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
559777 struct vfsmount *mnt, __u32 mask,
560
- unsigned int flags)
778
+ unsigned int flags, __u32 umask)
561779 {
562780 return fanotify_remove_mark(group, &real_mount(mnt)->mnt_fsnotify_marks,
563
- mask, flags);
781
+ mask, flags, umask);
782
+}
783
+
784
+static int fanotify_remove_sb_mark(struct fsnotify_group *group,
785
+ struct super_block *sb, __u32 mask,
786
+ unsigned int flags, __u32 umask)
787
+{
788
+ return fanotify_remove_mark(group, &sb->s_fsnotify_marks, mask,
789
+ flags, umask);
564790 }
565791
566792 static int fanotify_remove_inode_mark(struct fsnotify_group *group,
567793 struct inode *inode, __u32 mask,
568
- unsigned int flags)
794
+ unsigned int flags, __u32 umask)
569795 {
570796 return fanotify_remove_mark(group, &inode->i_fsnotify_marks, mask,
571
- flags);
797
+ flags, umask);
572798 }
573799
574800 static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
....@@ -579,19 +805,10 @@
579805
580806 spin_lock(&fsn_mark->lock);
581807 if (!(flags & FAN_MARK_IGNORED_MASK)) {
582
- __u32 tmask = fsn_mark->mask | mask;
583
-
584
- if (flags & FAN_MARK_ONDIR)
585
- tmask |= FAN_ONDIR;
586
-
587808 oldmask = fsn_mark->mask;
588
- fsn_mark->mask = tmask;
809
+ fsn_mark->mask |= mask;
589810 } else {
590
- __u32 tmask = fsn_mark->ignored_mask | mask;
591
- if (flags & FAN_MARK_ONDIR)
592
- tmask |= FAN_ONDIR;
593
-
594
- fsn_mark->ignored_mask = tmask;
811
+ fsn_mark->ignored_mask |= mask;
595812 if (flags & FAN_MARK_IGNORED_SURV_MODIFY)
596813 fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY;
597814 }
....@@ -602,7 +819,8 @@
602819
603820 static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
604821 fsnotify_connp_t *connp,
605
- unsigned int type)
822
+ unsigned int type,
823
+ __kernel_fsid_t *fsid)
606824 {
607825 struct fsnotify_mark *mark;
608826 int ret;
....@@ -615,7 +833,7 @@
615833 return ERR_PTR(-ENOMEM);
616834
617835 fsnotify_init_mark(mark, group);
618
- ret = fsnotify_add_mark_locked(mark, connp, type, 0);
836
+ ret = fsnotify_add_mark_locked(mark, connp, type, 0, fsid);
619837 if (ret) {
620838 fsnotify_put_mark(mark);
621839 return ERR_PTR(ret);
....@@ -627,7 +845,8 @@
627845
628846 static int fanotify_add_mark(struct fsnotify_group *group,
629847 fsnotify_connp_t *connp, unsigned int type,
630
- __u32 mask, unsigned int flags)
848
+ __u32 mask, unsigned int flags,
849
+ __kernel_fsid_t *fsid)
631850 {
632851 struct fsnotify_mark *fsn_mark;
633852 __u32 added;
....@@ -635,7 +854,7 @@
635854 mutex_lock(&group->mark_mutex);
636855 fsn_mark = fsnotify_find_mark(connp, group);
637856 if (!fsn_mark) {
638
- fsn_mark = fanotify_add_new_mark(group, connp, type);
857
+ fsn_mark = fanotify_add_new_mark(group, connp, type, fsid);
639858 if (IS_ERR(fsn_mark)) {
640859 mutex_unlock(&group->mark_mutex);
641860 return PTR_ERR(fsn_mark);
....@@ -652,15 +871,23 @@
652871
653872 static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
654873 struct vfsmount *mnt, __u32 mask,
655
- unsigned int flags)
874
+ unsigned int flags, __kernel_fsid_t *fsid)
656875 {
657876 return fanotify_add_mark(group, &real_mount(mnt)->mnt_fsnotify_marks,
658
- FSNOTIFY_OBJ_TYPE_VFSMOUNT, mask, flags);
877
+ FSNOTIFY_OBJ_TYPE_VFSMOUNT, mask, flags, fsid);
878
+}
879
+
880
+static int fanotify_add_sb_mark(struct fsnotify_group *group,
881
+ struct super_block *sb, __u32 mask,
882
+ unsigned int flags, __kernel_fsid_t *fsid)
883
+{
884
+ return fanotify_add_mark(group, &sb->s_fsnotify_marks,
885
+ FSNOTIFY_OBJ_TYPE_SB, mask, flags, fsid);
659886 }
660887
661888 static int fanotify_add_inode_mark(struct fsnotify_group *group,
662889 struct inode *inode, __u32 mask,
663
- unsigned int flags)
890
+ unsigned int flags, __kernel_fsid_t *fsid)
664891 {
665892 pr_debug("%s: group=%p inode=%p\n", __func__, group, inode);
666893
....@@ -671,11 +898,25 @@
671898 */
672899 if ((flags & FAN_MARK_IGNORED_MASK) &&
673900 !(flags & FAN_MARK_IGNORED_SURV_MODIFY) &&
674
- (atomic_read(&inode->i_writecount) > 0))
901
+ inode_is_open_for_write(inode))
675902 return 0;
676903
677904 return fanotify_add_mark(group, &inode->i_fsnotify_marks,
678
- FSNOTIFY_OBJ_TYPE_INODE, mask, flags);
905
+ FSNOTIFY_OBJ_TYPE_INODE, mask, flags, fsid);
906
+}
907
+
908
+static struct fsnotify_event *fanotify_alloc_overflow_event(void)
909
+{
910
+ struct fanotify_event *oevent;
911
+
912
+ oevent = kmalloc(sizeof(*oevent), GFP_KERNEL_ACCOUNT);
913
+ if (!oevent)
914
+ return NULL;
915
+
916
+ fanotify_init_event(oevent, 0, FS_Q_OVERFLOW);
917
+ oevent->type = FANOTIFY_EVENT_TYPE_OVERFLOW;
918
+
919
+ return &oevent->fse;
679920 }
680921
681922 /* fanotify syscalls */
....@@ -684,18 +925,19 @@
684925 struct fsnotify_group *group;
685926 int f_flags, fd;
686927 struct user_struct *user;
687
- struct fanotify_event_info *oevent;
928
+ unsigned int fid_mode = flags & FANOTIFY_FID_BITS;
929
+ unsigned int class = flags & FANOTIFY_CLASS_BITS;
688930
689
- pr_debug("%s: flags=%d event_f_flags=%d\n",
690
- __func__, flags, event_f_flags);
931
+ pr_debug("%s: flags=%x event_f_flags=%x\n",
932
+ __func__, flags, event_f_flags);
691933
692934 if (!capable(CAP_SYS_ADMIN))
693935 return -EPERM;
694936
695937 #ifdef CONFIG_AUDITSYSCALL
696
- if (flags & ~(FAN_ALL_INIT_FLAGS | FAN_ENABLE_AUDIT))
938
+ if (flags & ~(FANOTIFY_INIT_FLAGS | FAN_ENABLE_AUDIT))
697939 #else
698
- if (flags & ~FAN_ALL_INIT_FLAGS)
940
+ if (flags & ~FANOTIFY_INIT_FLAGS)
699941 #endif
700942 return -EINVAL;
701943
....@@ -710,6 +952,16 @@
710952 default:
711953 return -EINVAL;
712954 }
955
+
956
+ if (fid_mode && class != FAN_CLASS_NOTIF)
957
+ return -EINVAL;
958
+
959
+ /*
960
+ * Child name is reported with parent fid so requires dir fid.
961
+ * We can report both child fid and dir fid with or without name.
962
+ */
963
+ if ((fid_mode & FAN_REPORT_NAME) && !(fid_mode & FAN_REPORT_DIR_FID))
964
+ return -EINVAL;
713965
714966 user = get_current_user();
715967 if (atomic_read(&user->fanotify_listeners) > FANOTIFY_DEFAULT_MAX_LISTENERS) {
....@@ -731,22 +983,22 @@
731983 }
732984
733985 group->fanotify_data.user = user;
986
+ group->fanotify_data.flags = flags;
734987 atomic_inc(&user->fanotify_listeners);
735988 group->memcg = get_mem_cgroup_from_mm(current->mm);
736989
737
- oevent = fanotify_alloc_event(group, NULL, FS_Q_OVERFLOW, NULL);
738
- if (unlikely(!oevent)) {
990
+ group->overflow_event = fanotify_alloc_overflow_event();
991
+ if (unlikely(!group->overflow_event)) {
739992 fd = -ENOMEM;
740993 goto out_destroy_group;
741994 }
742
- group->overflow_event = &oevent->fse;
743995
744996 if (force_o_largefile())
745997 event_f_flags |= O_LARGEFILE;
746998 group->fanotify_data.f_flags = event_f_flags;
747999 init_waitqueue_head(&group->fanotify_data.access_waitq);
7481000 INIT_LIST_HEAD(&group->fanotify_data.access_list);
749
- switch (flags & FAN_ALL_CLASS_BITS) {
1001
+ switch (class) {
7501002 case FAN_CLASS_NOTIF:
7511003 group->priority = FS_PRIO_0;
7521004 break;
....@@ -783,7 +1035,6 @@
7831035 fd = -EPERM;
7841036 if (!capable(CAP_AUDIT_WRITE))
7851037 goto out_destroy_group;
786
- group->fanotify_data.audit = true;
7871038 }
7881039
7891040 fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
....@@ -797,6 +1048,82 @@
7971048 return fd;
7981049 }
7991050
1051
+/* Check if filesystem can encode a unique fid */
1052
+static int fanotify_test_fid(struct path *path, __kernel_fsid_t *fsid)
1053
+{
1054
+ __kernel_fsid_t root_fsid;
1055
+ int err;
1056
+
1057
+ /*
1058
+ * Make sure path is not in filesystem with zero fsid (e.g. tmpfs).
1059
+ */
1060
+ err = vfs_get_fsid(path->dentry, fsid);
1061
+ if (err)
1062
+ return err;
1063
+
1064
+ if (!fsid->val[0] && !fsid->val[1])
1065
+ return -ENODEV;
1066
+
1067
+ /*
1068
+ * Make sure path is not inside a filesystem subvolume (e.g. btrfs)
1069
+ * which uses a different fsid than sb root.
1070
+ */
1071
+ err = vfs_get_fsid(path->dentry->d_sb->s_root, &root_fsid);
1072
+ if (err)
1073
+ return err;
1074
+
1075
+ if (root_fsid.val[0] != fsid->val[0] ||
1076
+ root_fsid.val[1] != fsid->val[1])
1077
+ return -EXDEV;
1078
+
1079
+ /*
1080
+ * We need to make sure that the file system supports at least
1081
+ * encoding a file handle so user can use name_to_handle_at() to
1082
+ * compare fid returned with event to the file handle of watched
1083
+ * objects. However, name_to_handle_at() requires that the
1084
+ * filesystem also supports decoding file handles.
1085
+ */
1086
+ if (!path->dentry->d_sb->s_export_op ||
1087
+ !path->dentry->d_sb->s_export_op->fh_to_dentry)
1088
+ return -EOPNOTSUPP;
1089
+
1090
+ return 0;
1091
+}
1092
+
1093
+static int fanotify_events_supported(struct path *path, __u64 mask,
1094
+ unsigned int flags)
1095
+{
1096
+ unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS;
1097
+
1098
+ /*
1099
+ * Some filesystems such as 'proc' acquire unusual locks when opening
1100
+ * files. For them fanotify permission events have high chances of
1101
+ * deadlocking the system - open done when reporting fanotify event
1102
+ * blocks on this "unusual" lock while another process holding the lock
1103
+ * waits for fanotify permission event to be answered. Just disallow
1104
+ * permission events for such filesystems.
1105
+ */
1106
+ if (mask & FANOTIFY_PERM_EVENTS &&
1107
+ path->mnt->mnt_sb->s_type->fs_flags & FS_DISALLOW_NOTIFY_PERM)
1108
+ return -EINVAL;
1109
+
1110
+ /*
1111
+ * mount and sb marks are not allowed on kernel internal pseudo fs,
1112
+ * like pipe_mnt, because that would subscribe to events on all the
1113
+ * anonynous pipes in the system.
1114
+ *
1115
+ * SB_NOUSER covers all of the internal pseudo fs whose objects are not
1116
+ * exposed to user's mount namespace, but there are other SB_KERNMOUNT
1117
+ * fs, like nsfs, debugfs, for which the value of allowing sb and mount
1118
+ * mark is questionable. For now we leave them alone.
1119
+ */
1120
+ if (mark_type != FAN_MARK_INODE &&
1121
+ path->mnt->mnt_sb->s_flags & SB_NOUSER)
1122
+ return -EINVAL;
1123
+
1124
+ return 0;
1125
+}
1126
+
8001127 static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
8011128 int dfd, const char __user *pathname)
8021129 {
....@@ -805,7 +1132,12 @@
8051132 struct fsnotify_group *group;
8061133 struct fd f;
8071134 struct path path;
808
- u32 valid_mask = FAN_ALL_EVENTS | FAN_EVENT_ON_CHILD;
1135
+ __kernel_fsid_t __fsid, *fsid = NULL;
1136
+ u32 valid_mask = FANOTIFY_EVENTS | FANOTIFY_EVENT_FLAGS;
1137
+ unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS;
1138
+ bool ignored = flags & FAN_MARK_IGNORED_MASK;
1139
+ unsigned int obj_type, fid_mode;
1140
+ u32 umask = 0;
8091141 int ret;
8101142
8111143 pr_debug("%s: fanotify_fd=%d flags=%x dfd=%d pathname=%p mask=%llx\n",
....@@ -815,32 +1147,46 @@
8151147 if (mask & ((__u64)0xffffffff << 32))
8161148 return -EINVAL;
8171149
818
- if (flags & ~FAN_ALL_MARK_FLAGS)
1150
+ if (flags & ~FANOTIFY_MARK_FLAGS)
8191151 return -EINVAL;
1152
+
1153
+ switch (mark_type) {
1154
+ case FAN_MARK_INODE:
1155
+ obj_type = FSNOTIFY_OBJ_TYPE_INODE;
1156
+ break;
1157
+ case FAN_MARK_MOUNT:
1158
+ obj_type = FSNOTIFY_OBJ_TYPE_VFSMOUNT;
1159
+ break;
1160
+ case FAN_MARK_FILESYSTEM:
1161
+ obj_type = FSNOTIFY_OBJ_TYPE_SB;
1162
+ break;
1163
+ default:
1164
+ return -EINVAL;
1165
+ }
1166
+
8201167 switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {
821
- case FAN_MARK_ADD: /* fallthrough */
1168
+ case FAN_MARK_ADD:
8221169 case FAN_MARK_REMOVE:
8231170 if (!mask)
8241171 return -EINVAL;
8251172 break;
8261173 case FAN_MARK_FLUSH:
827
- if (flags & ~(FAN_MARK_MOUNT | FAN_MARK_FLUSH))
1174
+ if (flags & ~(FANOTIFY_MARK_TYPE_BITS | FAN_MARK_FLUSH))
8281175 return -EINVAL;
8291176 break;
8301177 default:
8311178 return -EINVAL;
8321179 }
8331180
834
- if (mask & FAN_ONDIR) {
835
- flags |= FAN_MARK_ONDIR;
836
- mask &= ~FAN_ONDIR;
837
- }
838
-
8391181 if (IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS))
840
- valid_mask |= FAN_ALL_PERM_EVENTS;
1182
+ valid_mask |= FANOTIFY_PERM_EVENTS;
8411183
8421184 if (mask & ~valid_mask)
8431185 return -EINVAL;
1186
+
1187
+ /* Event flags (ONDIR, ON_CHILD) are meaningless in ignored mask */
1188
+ if (ignored)
1189
+ mask &= ~FANOTIFY_EVENT_FLAGS;
8441190
8451191 f = fdget(fanotify_fd);
8461192 if (unlikely(!f.file))
....@@ -857,73 +1203,123 @@
8571203 * allowed to set permissions events.
8581204 */
8591205 ret = -EINVAL;
860
- if (mask & FAN_ALL_PERM_EVENTS &&
1206
+ if (mask & FANOTIFY_PERM_EVENTS &&
8611207 group->priority == FS_PRIO_0)
1208
+ goto fput_and_out;
1209
+
1210
+ /*
1211
+ * Events with data type inode do not carry enough information to report
1212
+ * event->fd, so we do not allow setting a mask for inode events unless
1213
+ * group supports reporting fid.
1214
+ * inode events are not supported on a mount mark, because they do not
1215
+ * carry enough information (i.e. path) to be filtered by mount point.
1216
+ */
1217
+ fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS);
1218
+ if (mask & FANOTIFY_INODE_EVENTS &&
1219
+ (!fid_mode || mark_type == FAN_MARK_MOUNT))
8621220 goto fput_and_out;
8631221
8641222 if (flags & FAN_MARK_FLUSH) {
8651223 ret = 0;
866
- if (flags & FAN_MARK_MOUNT)
1224
+ if (mark_type == FAN_MARK_MOUNT)
8671225 fsnotify_clear_vfsmount_marks_by_group(group);
1226
+ else if (mark_type == FAN_MARK_FILESYSTEM)
1227
+ fsnotify_clear_sb_marks_by_group(group);
8681228 else
8691229 fsnotify_clear_inode_marks_by_group(group);
8701230 goto fput_and_out;
8711231 }
8721232
873
- ret = fanotify_find_path(dfd, pathname, &path, flags);
1233
+ ret = fanotify_find_path(dfd, pathname, &path, flags,
1234
+ (mask & ALL_FSNOTIFY_EVENTS), obj_type);
8741235 if (ret)
8751236 goto fput_and_out;
8761237
1238
+ if (flags & FAN_MARK_ADD) {
1239
+ ret = fanotify_events_supported(&path, mask, flags);
1240
+ if (ret)
1241
+ goto path_put_and_out;
1242
+ }
1243
+
1244
+ if (fid_mode) {
1245
+ ret = fanotify_test_fid(&path, &__fsid);
1246
+ if (ret)
1247
+ goto path_put_and_out;
1248
+
1249
+ fsid = &__fsid;
1250
+ }
1251
+
8771252 /* inode held in place by reference to path; group by fget on fd */
878
- if (!(flags & FAN_MARK_MOUNT))
1253
+ if (mark_type == FAN_MARK_INODE)
8791254 inode = path.dentry->d_inode;
8801255 else
8811256 mnt = path.mnt;
8821257
1258
+ /* Mask out FAN_EVENT_ON_CHILD flag for sb/mount/non-dir marks */
1259
+ if (mnt || !S_ISDIR(inode->i_mode)) {
1260
+ mask &= ~FAN_EVENT_ON_CHILD;
1261
+ umask = FAN_EVENT_ON_CHILD;
1262
+ /*
1263
+ * If group needs to report parent fid, register for getting
1264
+ * events with parent/name info for non-directory.
1265
+ */
1266
+ if ((fid_mode & FAN_REPORT_DIR_FID) &&
1267
+ (flags & FAN_MARK_ADD) && !ignored)
1268
+ mask |= FAN_EVENT_ON_CHILD;
1269
+ }
1270
+
8831271 /* create/update an inode mark */
8841272 switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE)) {
8851273 case FAN_MARK_ADD:
886
- if (flags & FAN_MARK_MOUNT)
887
- ret = fanotify_add_vfsmount_mark(group, mnt, mask, flags);
1274
+ if (mark_type == FAN_MARK_MOUNT)
1275
+ ret = fanotify_add_vfsmount_mark(group, mnt, mask,
1276
+ flags, fsid);
1277
+ else if (mark_type == FAN_MARK_FILESYSTEM)
1278
+ ret = fanotify_add_sb_mark(group, mnt->mnt_sb, mask,
1279
+ flags, fsid);
8881280 else
889
- ret = fanotify_add_inode_mark(group, inode, mask, flags);
1281
+ ret = fanotify_add_inode_mark(group, inode, mask,
1282
+ flags, fsid);
8901283 break;
8911284 case FAN_MARK_REMOVE:
892
- if (flags & FAN_MARK_MOUNT)
893
- ret = fanotify_remove_vfsmount_mark(group, mnt, mask, flags);
1285
+ if (mark_type == FAN_MARK_MOUNT)
1286
+ ret = fanotify_remove_vfsmount_mark(group, mnt, mask,
1287
+ flags, umask);
1288
+ else if (mark_type == FAN_MARK_FILESYSTEM)
1289
+ ret = fanotify_remove_sb_mark(group, mnt->mnt_sb, mask,
1290
+ flags, umask);
8941291 else
895
- ret = fanotify_remove_inode_mark(group, inode, mask, flags);
1292
+ ret = fanotify_remove_inode_mark(group, inode, mask,
1293
+ flags, umask);
8961294 break;
8971295 default:
8981296 ret = -EINVAL;
8991297 }
9001298
1299
+path_put_and_out:
9011300 path_put(&path);
9021301 fput_and_out:
9031302 fdput(f);
9041303 return ret;
9051304 }
9061305
1306
+#ifndef CONFIG_ARCH_SPLIT_ARG64
9071307 SYSCALL_DEFINE5(fanotify_mark, int, fanotify_fd, unsigned int, flags,
9081308 __u64, mask, int, dfd,
9091309 const char __user *, pathname)
9101310 {
9111311 return do_fanotify_mark(fanotify_fd, flags, mask, dfd, pathname);
9121312 }
1313
+#endif
9131314
914
-#ifdef CONFIG_COMPAT
915
-COMPAT_SYSCALL_DEFINE6(fanotify_mark,
1315
+#if defined(CONFIG_ARCH_SPLIT_ARG64) || defined(CONFIG_COMPAT)
1316
+SYSCALL32_DEFINE6(fanotify_mark,
9161317 int, fanotify_fd, unsigned int, flags,
917
- __u32, mask0, __u32, mask1, int, dfd,
1318
+ SC_ARG64(mask), int, dfd,
9181319 const char __user *, pathname)
9191320 {
920
- return do_fanotify_mark(fanotify_fd, flags,
921
-#ifdef __BIG_ENDIAN
922
- ((__u64)mask0 << 32) | mask1,
923
-#else
924
- ((__u64)mask1 << 32) | mask0,
925
-#endif
926
- dfd, pathname);
1321
+ return do_fanotify_mark(fanotify_fd, flags, SC_VAL64(__u64, mask),
1322
+ dfd, pathname);
9271323 }
9281324 #endif
9291325
....@@ -934,12 +1330,18 @@
9341330 */
9351331 static int __init fanotify_user_setup(void)
9361332 {
1333
+ BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 10);
1334
+ BUILD_BUG_ON(HWEIGHT32(FANOTIFY_MARK_FLAGS) != 9);
1335
+
9371336 fanotify_mark_cache = KMEM_CACHE(fsnotify_mark,
9381337 SLAB_PANIC|SLAB_ACCOUNT);
939
- fanotify_event_cachep = KMEM_CACHE(fanotify_event_info, SLAB_PANIC);
1338
+ fanotify_fid_event_cachep = KMEM_CACHE(fanotify_fid_event,
1339
+ SLAB_PANIC);
1340
+ fanotify_path_event_cachep = KMEM_CACHE(fanotify_path_event,
1341
+ SLAB_PANIC);
9401342 if (IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS)) {
9411343 fanotify_perm_event_cachep =
942
- KMEM_CACHE(fanotify_perm_event_info, SLAB_PANIC);
1344
+ KMEM_CACHE(fanotify_perm_event, SLAB_PANIC);
9431345 }
9441346
9451347 return 0;