hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/fs/notify/inotify/inotify_user.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * fs/inotify_user.c - inotify support for userspace
34 *
....@@ -10,16 +11,6 @@
1011 *
1112 * Copyright (C) 2009 Eric Paris <Red Hat Inc>
1213 * inotify was largely rewriten to make use of the fsnotify infrastructure
13
- *
14
- * This program is free software; you can redistribute it and/or modify it
15
- * under the terms of the GNU General Public License as published by the
16
- * Free Software Foundation; either version 2, or (at your option) any
17
- * later version.
18
- *
19
- * This program is distributed in the hope that it will be useful, but
20
- * WITHOUT ANY WARRANTY; without even the implied warranty of
21
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22
- * General Public License for more details.
2314 */
2415
2516 #include <linux/file.h>
....@@ -39,6 +30,7 @@
3930 #include <linux/poll.h>
4031 #include <linux/wait.h>
4132 #include <linux/memcontrol.h>
33
+#include <linux/security.h>
4234
4335 #include "inotify.h"
4436 #include "../fdinfo.h"
....@@ -54,8 +46,6 @@
5446
5547 #include <linux/sysctl.h>
5648
57
-static int zero;
58
-
5949 struct ctl_table inotify_table[] = {
6050 {
6151 .procname = "max_user_instances",
....@@ -63,7 +53,7 @@
6353 .maxlen = sizeof(int),
6454 .mode = 0644,
6555 .proc_handler = proc_dointvec_minmax,
66
- .extra1 = &zero,
56
+ .extra1 = SYSCTL_ZERO,
6757 },
6858 {
6959 .procname = "max_user_watches",
....@@ -71,7 +61,7 @@
7161 .maxlen = sizeof(int),
7262 .mode = 0644,
7363 .proc_handler = proc_dointvec_minmax,
74
- .extra1 = &zero,
64
+ .extra1 = SYSCTL_ZERO,
7565 },
7666 {
7767 .procname = "max_queued_events",
....@@ -79,24 +69,26 @@
7969 .maxlen = sizeof(int),
8070 .mode = 0644,
8171 .proc_handler = proc_dointvec_minmax,
82
- .extra1 = &zero
72
+ .extra1 = SYSCTL_ZERO
8373 },
8474 { }
8575 };
8676 #endif /* CONFIG_SYSCTL */
8777
88
-static inline __u32 inotify_arg_to_mask(u32 arg)
78
+static inline __u32 inotify_arg_to_mask(struct inode *inode, u32 arg)
8979 {
9080 __u32 mask;
9181
9282 /*
93
- * everything should accept their own ignored, cares about children,
94
- * and should receive events when the inode is unmounted
83
+ * Everything should accept their own ignored and should receive events
84
+ * when the inode is unmounted. All directories care about children.
9585 */
96
- mask = (FS_IN_IGNORED | FS_EVENT_ON_CHILD | FS_UNMOUNT);
86
+ mask = (FS_IN_IGNORED | FS_UNMOUNT);
87
+ if (S_ISDIR(inode->i_mode))
88
+ mask |= FS_EVENT_ON_CHILD;
9789
9890 /* mask off the flags used to open the fd */
99
- mask |= (arg & (IN_ALL_EVENTS | IN_ONESHOT | IN_EXCL_UNLINK));
91
+ mask |= (arg & INOTIFY_USER_MASK);
10092
10193 return mask;
10294 }
....@@ -189,7 +181,7 @@
189181 */
190182 pad_name_len = round_event_name_len(fsn_event);
191183 inotify_event.len = pad_name_len;
192
- inotify_event.mask = inotify_mask_to_arg(fsn_event->mask);
184
+ inotify_event.mask = inotify_mask_to_arg(event->mask);
193185 inotify_event.wd = event->wd;
194186 inotify_event.cookie = event->sync_cookie;
195187
....@@ -342,7 +334,8 @@
342334 /*
343335 * find_inode - resolve a user-given path to a specific inode
344336 */
345
-static int inotify_find_inode(const char __user *dirname, struct path *path, unsigned flags)
337
+static int inotify_find_inode(const char __user *dirname, struct path *path,
338
+ unsigned int flags, __u64 mask)
346339 {
347340 int error;
348341
....@@ -350,9 +343,16 @@
350343 if (error)
351344 return error;
352345 /* you can only watch an inode if you have read permissions on it */
353
- error = inode_permission2(path->mnt, path->dentry->d_inode, MAY_READ);
346
+ error = inode_permission(path->dentry->d_inode, MAY_READ);
347
+ if (error) {
348
+ path_put(path);
349
+ return error;
350
+ }
351
+ error = security_path_notify(path, mask,
352
+ FSNOTIFY_OBJ_TYPE_INODE);
354353 if (error)
355354 path_put(path);
355
+
356356 return error;
357357 }
358358
....@@ -486,14 +486,10 @@
486486 struct fsnotify_group *group)
487487 {
488488 struct inotify_inode_mark *i_mark;
489
- struct fsnotify_iter_info iter_info = { };
490
-
491
- fsnotify_iter_set_report_type_mark(&iter_info, FSNOTIFY_OBJ_TYPE_INODE,
492
- fsn_mark);
493489
494490 /* Queue ignore event for the watch */
495
- inotify_handle_event(group, NULL, FS_IN_IGNORED, NULL,
496
- FSNOTIFY_EVENT_NONE, NULL, 0, &iter_info);
491
+ inotify_handle_inode_event(fsn_mark, FS_IN_IGNORED, NULL, NULL, NULL,
492
+ 0);
497493
498494 i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
499495 /* remove this mark from the idr */
....@@ -514,7 +510,7 @@
514510 int create = (arg & IN_MASK_CREATE);
515511 int ret;
516512
517
- mask = inotify_arg_to_mask(arg);
513
+ mask = inotify_arg_to_mask(inode, arg);
518514
519515 fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, group);
520516 if (!fsn_mark)
....@@ -567,7 +563,7 @@
567563 struct idr *idr = &group->inotify_data.idr;
568564 spinlock_t *idr_lock = &group->inotify_data.idr_lock;
569565
570
- mask = inotify_arg_to_mask(arg);
566
+ mask = inotify_arg_to_mask(inode, arg);
571567
572568 tmp_i_mark = kmem_cache_alloc(inotify_inode_mark_cachep, GFP_KERNEL);
573569 if (unlikely(!tmp_i_mark))
....@@ -637,7 +633,8 @@
637633 return ERR_PTR(-ENOMEM);
638634 }
639635 group->overflow_event = &oevent->fse;
640
- fsnotify_init_event(group->overflow_event, NULL, FS_Q_OVERFLOW);
636
+ fsnotify_init_event(group->overflow_event, 0);
637
+ oevent->mask = FS_Q_OVERFLOW;
641638 oevent->wd = -1;
642639 oevent->sync_cookie = 0;
643640 oevent->name_len = 0;
....@@ -745,7 +742,8 @@
745742 if (mask & IN_ONLYDIR)
746743 flags |= LOOKUP_DIRECTORY;
747744
748
- ret = inotify_find_inode(pathname, &path, flags);
745
+ ret = inotify_find_inode(pathname, &path, flags,
746
+ (mask & IN_ALL_EVENTS));
749747 if (ret)
750748 goto fput_and_out;
751749
....@@ -776,20 +774,18 @@
776774 struct fsnotify_group *group;
777775 struct inotify_inode_mark *i_mark;
778776 struct fd f;
779
- int ret = 0;
777
+ int ret = -EINVAL;
780778
781779 f = fdget(fd);
782780 if (unlikely(!f.file))
783781 return -EBADF;
784782
785783 /* verify that this is indeed an inotify instance */
786
- ret = -EINVAL;
787784 if (unlikely(f.file->f_op != &inotify_fops))
788785 goto out;
789786
790787 group = f.file->private_data;
791788
792
- ret = -EINVAL;
793789 i_mark = inotify_idr_find(group, wd);
794790 if (unlikely(!i_mark))
795791 goto out;
....@@ -832,7 +828,7 @@
832828 BUILD_BUG_ON(IN_ISDIR != FS_ISDIR);
833829 BUILD_BUG_ON(IN_ONESHOT != FS_IN_ONESHOT);
834830
835
- BUG_ON(hweight32(ALL_INOTIFY_BITS) != 22);
831
+ BUILD_BUG_ON(HWEIGHT32(ALL_INOTIFY_BITS) != 22);
836832
837833 inotify_inode_mark_cachep = KMEM_CACHE(inotify_inode_mark,
838834 SLAB_PANIC|SLAB_ACCOUNT);