hc
2024-05-11 04dd17822334871b23ea2862f7798fb0e0007777
kernel/fs/notify/dnotify/dnotify.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Directory notifications for Linux.
34 *
....@@ -5,16 +6,6 @@
56 *
67 * Copyright (C) 2009 Eric Paris <Red Hat Inc>
78 * dnotify was largly rewritten to use the new fsnotify infrastructure
8
- *
9
- * This program is free software; you can redistribute it and/or modify it
10
- * under the terms of the GNU General Public License as published by the
11
- * Free Software Foundation; either version 2, or (at your option) any
12
- * later version.
13
- *
14
- * This program is distributed in the hope that it will be useful, but
15
- * WITHOUT ANY WARRANTY; without even the implied warranty of
16
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
- * General Public License for more details.
189 */
1910 #include <linux/fs.h>
2011 #include <linux/module.h>
....@@ -22,6 +13,7 @@
2213 #include <linux/sched/signal.h>
2314 #include <linux/dnotify.h>
2415 #include <linux/init.h>
16
+#include <linux/security.h>
2517 #include <linux/spinlock.h>
2618 #include <linux/slab.h>
2719 #include <linux/fdtable.h>
....@@ -78,13 +70,10 @@
7870 * destroy the dnotify struct if it was not registered to receive multiple
7971 * events.
8072 */
81
-static int dnotify_handle_event(struct fsnotify_group *group,
82
- struct inode *inode,
83
- u32 mask, const void *data, int data_type,
84
- const unsigned char *file_name, u32 cookie,
85
- struct fsnotify_iter_info *iter_info)
73
+static int dnotify_handle_event(struct fsnotify_mark *inode_mark, u32 mask,
74
+ struct inode *inode, struct inode *dir,
75
+ const struct qstr *name, u32 cookie)
8676 {
87
- struct fsnotify_mark *inode_mark = fsnotify_iter_inode_mark(iter_info);
8877 struct dnotify_mark *dn_mark;
8978 struct dnotify_struct *dn;
9079 struct dnotify_struct **prev;
....@@ -92,10 +81,7 @@
9281 __u32 test_mask = mask & ~FS_EVENT_ON_CHILD;
9382
9483 /* not a dir, dnotify doesn't care */
95
- if (!S_ISDIR(inode->i_mode))
96
- return 0;
97
-
98
- if (WARN_ON(fsnotify_iter_vfsmount_mark(iter_info)))
84
+ if (!dir && !(mask & FS_ISDIR))
9985 return 0;
10086
10187 dn_mark = container_of(inode_mark, struct dnotify_mark, fsn_mark);
....@@ -135,7 +121,7 @@
135121 }
136122
137123 static const struct fsnotify_ops dnotify_fsnotify_ops = {
138
- .handle_event = dnotify_handle_event,
124
+ .handle_inode_event = dnotify_handle_event,
139125 .free_mark = dnotify_free_mark,
140126 };
141127
....@@ -288,6 +274,17 @@
288274 goto out_err;
289275 }
290276
277
+ /*
278
+ * convert the userspace DN_* "arg" to the internal FS_*
279
+ * defined in fsnotify
280
+ */
281
+ mask = convert_arg(arg);
282
+
283
+ error = security_path_notify(&filp->f_path, mask,
284
+ FSNOTIFY_OBJ_TYPE_INODE);
285
+ if (error)
286
+ goto out_err;
287
+
291288 /* expect most fcntl to add new rather than augment old */
292289 dn = kmem_cache_alloc(dnotify_struct_cache, GFP_KERNEL);
293290 if (!dn) {
....@@ -301,9 +298,6 @@
301298 error = -ENOMEM;
302299 goto out_err;
303300 }
304
-
305
- /* convert the userspace DN_* "arg" to the internal FS_* defines in fsnotify */
306
- mask = convert_arg(arg);
307301
308302 /* set up the new_fsn_mark and new_dn_mark */
309303 new_fsn_mark = &new_dn_mark->fsn_mark;