blob: 8b4e2ad6d20822e10defdb6bc57b86967a9e5b5b [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001// SPDX-License-Identifier: GPL-2.0
Andreas Gruenbacher33d3dff2009-12-17 21:24:29 -05002#include <linux/fanotify.h>
Eric Paris11637e42009-12-17 21:24:25 -05003#include <linux/fcntl.h>
Eric Paris2a3edf82009-12-17 21:24:26 -05004#include <linux/file.h>
Eric Paris11637e42009-12-17 21:24:25 -05005#include <linux/fs.h>
Eric Paris52c923d2009-12-17 21:24:26 -05006#include <linux/anon_inodes.h>
Eric Paris11637e42009-12-17 21:24:25 -05007#include <linux/fsnotify_backend.h>
Eric Paris2a3edf82009-12-17 21:24:26 -05008#include <linux/init.h>
Eric Parisa1014f12009-12-17 21:24:26 -05009#include <linux/mount.h>
Eric Paris2a3edf82009-12-17 21:24:26 -050010#include <linux/namei.h>
Eric Parisa1014f12009-12-17 21:24:26 -050011#include <linux/poll.h>
Eric Paris11637e42009-12-17 21:24:25 -050012#include <linux/security.h>
13#include <linux/syscalls.h>
Tejun Heoe4e047a2010-05-20 01:36:28 +100014#include <linux/slab.h>
Eric Paris2a3edf82009-12-17 21:24:26 -050015#include <linux/types.h>
Eric Parisa1014f12009-12-17 21:24:26 -050016#include <linux/uaccess.h>
Al Viro91c2e0b2013-03-05 20:10:59 -050017#include <linux/compat.h>
Ingo Molnar174cd4b2017-02-02 19:15:33 +010018#include <linux/sched/signal.h>
Shakeel Buttd46eb14b2018-08-17 15:46:39 -070019#include <linux/memcontrol.h>
Amir Goldsteina8b13aa2019-01-10 19:04:36 +020020#include <linux/statfs.h>
21#include <linux/exportfs.h>
Eric Parisa1014f12009-12-17 21:24:26 -050022
23#include <asm/ioctls.h>
Eric Paris11637e42009-12-17 21:24:25 -050024
Al Viroc63181e2011-11-25 02:35:16 -050025#include "../../mount.h"
Cyrill Gorcunovbe771962012-12-17 16:05:12 -080026#include "../fdinfo.h"
Jan Kara7053aee2014-01-21 15:48:14 -080027#include "fanotify.h"
Al Viroc63181e2011-11-25 02:35:16 -050028
Eric Paris2529a0d2010-10-28 17:21:57 -040029#define FANOTIFY_DEFAULT_MAX_EVENTS 16384
Eric Parise7099d82010-10-28 17:21:57 -040030#define FANOTIFY_DEFAULT_MAX_MARKS 8192
Eric Paris4afeff82010-10-28 17:21:58 -040031#define FANOTIFY_DEFAULT_MAX_LISTENERS 128
Eric Paris2529a0d2010-10-28 17:21:57 -040032
Heinrich Schuchardt48149e92014-06-04 16:05:44 -070033/*
34 * All flags that may be specified in parameter event_f_flags of fanotify_init.
35 *
36 * Internal and external open flags are stored together in field f_flags of
37 * struct file. Only external open flags shall be allowed in event_f_flags.
38 * Internal flags like FMODE_NONOTIFY, FMODE_EXEC, FMODE_NOCMTIME shall be
39 * excluded.
40 */
41#define FANOTIFY_INIT_ALL_EVENT_F_BITS ( \
42 O_ACCMODE | O_APPEND | O_NONBLOCK | \
43 __O_SYNC | O_DSYNC | O_CLOEXEC | \
44 O_LARGEFILE | O_NOATIME )
45
Andreas Gruenbacher33d3dff2009-12-17 21:24:29 -050046extern const struct fsnotify_ops fanotify_fsnotify_ops;
Eric Paris11637e42009-12-17 21:24:25 -050047
Jan Kara054c6362016-12-21 18:06:12 +010048struct kmem_cache *fanotify_mark_cache __read_mostly;
Jan Kara7053aee2014-01-21 15:48:14 -080049struct kmem_cache *fanotify_event_cachep __read_mostly;
Jan Karaf0834412014-04-03 14:46:33 -070050struct kmem_cache *fanotify_perm_event_cachep __read_mostly;
Eric Paris2a3edf82009-12-17 21:24:26 -050051
Amir Goldstein5e469c82019-01-10 19:04:35 +020052#define FANOTIFY_EVENT_ALIGN 4
53
54static int fanotify_event_info_len(struct fanotify_event *event)
55{
56 if (!fanotify_event_has_fid(event))
57 return 0;
58
59 return roundup(sizeof(struct fanotify_event_info_fid) +
60 sizeof(struct file_handle) + event->fh_len,
61 FANOTIFY_EVENT_ALIGN);
62}
63
Eric Parisa1014f12009-12-17 21:24:26 -050064/*
65 * Get an fsnotify notification event if one exists and is small
66 * enough to fit in "count". Return an error pointer if the count
Jan Kara40873282019-01-08 14:02:44 +010067 * is not large enough. When permission event is dequeued, its state is
68 * updated accordingly.
Eric Parisa1014f12009-12-17 21:24:26 -050069 */
70static struct fsnotify_event *get_one_event(struct fsnotify_group *group,
71 size_t count)
72{
Amir Goldstein5e469c82019-01-10 19:04:35 +020073 size_t event_size = FAN_EVENT_METADATA_LEN;
Jan Kara8c554462019-01-08 13:52:31 +010074 struct fsnotify_event *fsn_event = NULL;
Eric Parisa1014f12009-12-17 21:24:26 -050075
76 pr_debug("%s: group=%p count=%zd\n", __func__, group, count);
77
Jan Kara8c554462019-01-08 13:52:31 +010078 spin_lock(&group->notification_lock);
Eric Parisa1014f12009-12-17 21:24:26 -050079 if (fsnotify_notify_queue_is_empty(group))
Jan Kara8c554462019-01-08 13:52:31 +010080 goto out;
Eric Parisa1014f12009-12-17 21:24:26 -050081
Amir Goldstein5e469c82019-01-10 19:04:35 +020082 if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) {
Jan Kara8c554462019-01-08 13:52:31 +010083 event_size += fanotify_event_info_len(
84 FANOTIFY_E(fsnotify_peek_first_event(group)));
Amir Goldstein5e469c82019-01-10 19:04:35 +020085 }
86
Jan Kara8c554462019-01-08 13:52:31 +010087 if (event_size > count) {
88 fsn_event = ERR_PTR(-EINVAL);
89 goto out;
90 }
91 fsn_event = fsnotify_remove_first_event(group);
Jan Kara40873282019-01-08 14:02:44 +010092 if (fanotify_is_perm_event(FANOTIFY_E(fsn_event)->mask))
93 FANOTIFY_PE(fsn_event)->state = FAN_EVENT_REPORTED;
Jan Kara8c554462019-01-08 13:52:31 +010094out:
95 spin_unlock(&group->notification_lock);
96 return fsn_event;
Eric Parisa1014f12009-12-17 21:24:26 -050097}
98
Al Viro352e3b22012-08-19 12:30:45 -040099static int create_fd(struct fsnotify_group *group,
Amir Goldstein33913992019-01-10 19:04:32 +0200100 struct fanotify_event *event,
Jan Kara7053aee2014-01-21 15:48:14 -0800101 struct file **file)
Eric Parisa1014f12009-12-17 21:24:26 -0500102{
103 int client_fd;
Eric Parisa1014f12009-12-17 21:24:26 -0500104 struct file *new_file;
105
Andreas Gruenbacher22aa4252009-12-17 21:24:26 -0500106 pr_debug("%s: group=%p event=%p\n", __func__, group, event);
Eric Parisa1014f12009-12-17 21:24:26 -0500107
Yann Droneaud0b37e092014-10-09 15:24:40 -0700108 client_fd = get_unused_fd_flags(group->fanotify_data.f_flags);
Eric Parisa1014f12009-12-17 21:24:26 -0500109 if (client_fd < 0)
110 return client_fd;
111
Eric Parisa1014f12009-12-17 21:24:26 -0500112 /*
113 * we need a new file handle for the userspace program so it can read even if it was
114 * originally opened O_WRONLY.
115 */
Eric Parisa1014f12009-12-17 21:24:26 -0500116 /* it's possible this event was an overflow event. in that case dentry and mnt
117 * are NULL; That's fine, just don't call dentry open */
Al Viro765927b2012-06-26 21:58:53 +0400118 if (event->path.dentry && event->path.mnt)
119 new_file = dentry_open(&event->path,
Eric Paris80af2582010-07-28 10:18:37 -0400120 group->fanotify_data.f_flags | FMODE_NONOTIFY,
Eric Parisa1014f12009-12-17 21:24:26 -0500121 current_cred());
122 else
123 new_file = ERR_PTR(-EOVERFLOW);
124 if (IS_ERR(new_file)) {
125 /*
126 * we still send an event even if we can't open the file. this
127 * can happen when say tasks are gone and we try to open their
128 * /proc files or we try to open a WRONLY file like in sysfs
129 * we just send the errno to userspace since there isn't much
130 * else we can do.
131 */
132 put_unused_fd(client_fd);
133 client_fd = PTR_ERR(new_file);
134 } else {
Al Viro352e3b22012-08-19 12:30:45 -0400135 *file = new_file;
Eric Parisa1014f12009-12-17 21:24:26 -0500136 }
137
Andreas Gruenbacher22aa4252009-12-17 21:24:26 -0500138 return client_fd;
Eric Parisa1014f12009-12-17 21:24:26 -0500139}
140
Jan Kara40873282019-01-08 14:02:44 +0100141/*
142 * Finish processing of permission event by setting it to ANSWERED state and
143 * drop group->notification_lock.
144 */
145static void finish_permission_event(struct fsnotify_group *group,
146 struct fanotify_perm_event *event,
147 unsigned int response)
148 __releases(&group->notification_lock)
149{
Jan Karafabf7f22019-01-08 15:18:02 +0100150 bool destroy = false;
151
Jan Kara40873282019-01-08 14:02:44 +0100152 assert_spin_locked(&group->notification_lock);
153 event->response = response;
Jan Karafabf7f22019-01-08 15:18:02 +0100154 if (event->state == FAN_EVENT_CANCELED)
155 destroy = true;
156 else
157 event->state = FAN_EVENT_ANSWERED;
Jan Kara40873282019-01-08 14:02:44 +0100158 spin_unlock(&group->notification_lock);
Jan Karafabf7f22019-01-08 15:18:02 +0100159 if (destroy)
160 fsnotify_destroy_event(group, &event->fae.fse);
Jan Kara40873282019-01-08 14:02:44 +0100161}
162
Eric Parisb2d87902009-12-17 21:24:34 -0500163static int process_access_response(struct fsnotify_group *group,
164 struct fanotify_response *response_struct)
165{
Amir Goldstein33913992019-01-10 19:04:32 +0200166 struct fanotify_perm_event *event;
Jan Karaf0834412014-04-03 14:46:33 -0700167 int fd = response_struct->fd;
168 int response = response_struct->response;
Eric Parisb2d87902009-12-17 21:24:34 -0500169
170 pr_debug("%s: group=%p fd=%d response=%d\n", __func__, group,
171 fd, response);
172 /*
173 * make sure the response is valid, if invalid we do nothing and either
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300174 * userspace can send a valid response or we will clean it up after the
Eric Parisb2d87902009-12-17 21:24:34 -0500175 * timeout
176 */
Steve Grubbde8cd832017-10-02 20:21:39 -0400177 switch (response & ~FAN_AUDIT) {
Eric Parisb2d87902009-12-17 21:24:34 -0500178 case FAN_ALLOW:
179 case FAN_DENY:
180 break;
181 default:
182 return -EINVAL;
183 }
184
185 if (fd < 0)
186 return -EINVAL;
187
Amir Goldstein96a71f22018-09-21 21:20:30 +0300188 if ((response & FAN_AUDIT) && !FAN_GROUP_FLAG(group, FAN_ENABLE_AUDIT))
Steve Grubbde8cd832017-10-02 20:21:39 -0400189 return -EINVAL;
190
Jan Karaaf6a5112019-01-08 13:28:18 +0100191 spin_lock(&group->notification_lock);
192 list_for_each_entry(event, &group->fanotify_data.access_list,
193 fae.fse.list) {
194 if (event->fd != fd)
195 continue;
Eric Parisb2d87902009-12-17 21:24:34 -0500196
Jan Karaaf6a5112019-01-08 13:28:18 +0100197 list_del_init(&event->fae.fse.list);
Jan Kara40873282019-01-08 14:02:44 +0100198 finish_permission_event(group, event, response);
Jan Karaaf6a5112019-01-08 13:28:18 +0100199 wake_up(&group->fanotify_data.access_waitq);
200 return 0;
201 }
202 spin_unlock(&group->notification_lock);
Eric Parisb2d87902009-12-17 21:24:34 -0500203
Jan Karaaf6a5112019-01-08 13:28:18 +0100204 return -ENOENT;
Eric Parisb2d87902009-12-17 21:24:34 -0500205}
Eric Parisb2d87902009-12-17 21:24:34 -0500206
Amir Goldstein5e469c82019-01-10 19:04:35 +0200207static int copy_fid_to_user(struct fanotify_event *event, char __user *buf)
208{
209 struct fanotify_event_info_fid info = { };
210 struct file_handle handle = { };
Jan Karab2d22b62019-03-12 12:42:37 +0100211 unsigned char bounce[FANOTIFY_INLINE_FH_LEN], *fh;
Amir Goldstein5e469c82019-01-10 19:04:35 +0200212 size_t fh_len = event->fh_len;
213 size_t len = fanotify_event_info_len(event);
214
215 if (!len)
216 return 0;
217
218 if (WARN_ON_ONCE(len < sizeof(info) + sizeof(handle) + fh_len))
219 return -EFAULT;
220
221 /* Copy event info fid header followed by vaiable sized file handle */
222 info.hdr.info_type = FAN_EVENT_INFO_TYPE_FID;
223 info.hdr.len = len;
224 info.fsid = event->fid.fsid;
225 if (copy_to_user(buf, &info, sizeof(info)))
226 return -EFAULT;
227
228 buf += sizeof(info);
229 len -= sizeof(info);
230 handle.handle_type = event->fh_type;
231 handle.handle_bytes = fh_len;
232 if (copy_to_user(buf, &handle, sizeof(handle)))
233 return -EFAULT;
234
235 buf += sizeof(handle);
236 len -= sizeof(handle);
Jan Karab2d22b62019-03-12 12:42:37 +0100237 /*
238 * For an inline fh, copy through stack to exclude the copy from
239 * usercopy hardening protections.
240 */
241 fh = fanotify_event_fh(event);
242 if (fh_len <= FANOTIFY_INLINE_FH_LEN) {
243 memcpy(bounce, fh, fh_len);
244 fh = bounce;
245 }
246 if (copy_to_user(buf, fh, fh_len))
Amir Goldstein5e469c82019-01-10 19:04:35 +0200247 return -EFAULT;
248
249 /* Pad with 0's */
250 buf += fh_len;
251 len -= fh_len;
252 WARN_ON_ONCE(len < 0 || len >= FANOTIFY_EVENT_ALIGN);
253 if (len > 0 && clear_user(buf, len))
254 return -EFAULT;
255
256 return 0;
257}
258
Eric Parisa1014f12009-12-17 21:24:26 -0500259static ssize_t copy_event_to_user(struct fsnotify_group *group,
Amir Goldsteinbb2f7b42019-01-10 19:04:33 +0200260 struct fsnotify_event *fsn_event,
Kees Cook5b03a472018-12-04 15:44:46 -0800261 char __user *buf, size_t count)
Eric Parisa1014f12009-12-17 21:24:26 -0500262{
Amir Goldsteinbb2f7b42019-01-10 19:04:33 +0200263 struct fanotify_event_metadata metadata;
264 struct fanotify_event *event;
265 struct file *f = NULL;
Amir Goldsteine9e0c892019-01-10 19:04:34 +0200266 int ret, fd = FAN_NOFD;
Eric Parisa1014f12009-12-17 21:24:26 -0500267
Amir Goldsteinbb2f7b42019-01-10 19:04:33 +0200268 pr_debug("%s: group=%p event=%p\n", __func__, group, fsn_event);
Eric Parisa1014f12009-12-17 21:24:26 -0500269
Amir Goldsteinbb2f7b42019-01-10 19:04:33 +0200270 event = container_of(fsn_event, struct fanotify_event, fse);
271 metadata.event_len = FAN_EVENT_METADATA_LEN;
272 metadata.metadata_len = FAN_EVENT_METADATA_LEN;
273 metadata.vers = FANOTIFY_METADATA_VERSION;
274 metadata.reserved = 0;
275 metadata.mask = event->mask & FANOTIFY_OUTGOING_EVENTS;
276 metadata.pid = pid_vnr(event->pid);
Eric Parisa1014f12009-12-17 21:24:26 -0500277
Amir Goldsteine9e0c892019-01-10 19:04:34 +0200278 if (fanotify_event_has_path(event)) {
Amir Goldsteinbb2f7b42019-01-10 19:04:33 +0200279 fd = create_fd(group, event, &f);
280 if (fd < 0)
281 return fd;
Amir Goldstein5e469c82019-01-10 19:04:35 +0200282 } else if (fanotify_event_has_fid(event)) {
283 metadata.event_len += fanotify_event_info_len(event);
Amir Goldsteinbb2f7b42019-01-10 19:04:33 +0200284 }
285 metadata.fd = fd;
286
Al Viro352e3b22012-08-19 12:30:45 -0400287 ret = -EFAULT;
Kees Cook5b03a472018-12-04 15:44:46 -0800288 /*
289 * Sanity check copy size in case get_one_event() and
290 * fill_event_metadata() event_len sizes ever get out of sync.
291 */
Amir Goldsteinbb2f7b42019-01-10 19:04:33 +0200292 if (WARN_ON_ONCE(metadata.event_len > count))
Al Viro352e3b22012-08-19 12:30:45 -0400293 goto out_close_fd;
294
Amir Goldstein5e469c82019-01-10 19:04:35 +0200295 if (copy_to_user(buf, &metadata, FAN_EVENT_METADATA_LEN))
Amir Goldsteinbb2f7b42019-01-10 19:04:33 +0200296 goto out_close_fd;
297
298 if (fanotify_is_perm_event(event->mask))
299 FANOTIFY_PE(fsn_event)->fd = fd;
Eric Parisb2d87902009-12-17 21:24:34 -0500300
Amir Goldstein5e469c82019-01-10 19:04:35 +0200301 if (fanotify_event_has_path(event)) {
Al Viro3587b1b2012-11-18 19:19:00 +0000302 fd_install(fd, f);
Amir Goldstein5e469c82019-01-10 19:04:35 +0200303 } else if (fanotify_event_has_fid(event)) {
304 ret = copy_fid_to_user(event, buf + FAN_EVENT_METADATA_LEN);
305 if (ret < 0)
306 return ret;
307 }
308
Amir Goldsteinbb2f7b42019-01-10 19:04:33 +0200309 return metadata.event_len;
Eric Parisb2d87902009-12-17 21:24:34 -0500310
Eric Parisb2d87902009-12-17 21:24:34 -0500311out_close_fd:
Al Viro352e3b22012-08-19 12:30:45 -0400312 if (fd != FAN_NOFD) {
313 put_unused_fd(fd);
314 fput(f);
315 }
Eric Parisb2d87902009-12-17 21:24:34 -0500316 return ret;
Eric Parisa1014f12009-12-17 21:24:26 -0500317}
318
319/* intofiy userspace file descriptor functions */
Al Viro076ccb72017-07-03 01:02:18 -0400320static __poll_t fanotify_poll(struct file *file, poll_table *wait)
Eric Parisa1014f12009-12-17 21:24:26 -0500321{
322 struct fsnotify_group *group = file->private_data;
Al Viro076ccb72017-07-03 01:02:18 -0400323 __poll_t ret = 0;
Eric Parisa1014f12009-12-17 21:24:26 -0500324
325 poll_wait(file, &group->notification_waitq, wait);
Jan Karac21dbe22016-10-07 16:56:52 -0700326 spin_lock(&group->notification_lock);
Eric Parisa1014f12009-12-17 21:24:26 -0500327 if (!fsnotify_notify_queue_is_empty(group))
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800328 ret = EPOLLIN | EPOLLRDNORM;
Jan Karac21dbe22016-10-07 16:56:52 -0700329 spin_unlock(&group->notification_lock);
Eric Parisa1014f12009-12-17 21:24:26 -0500330
331 return ret;
332}
333
334static ssize_t fanotify_read(struct file *file, char __user *buf,
335 size_t count, loff_t *pos)
336{
337 struct fsnotify_group *group;
338 struct fsnotify_event *kevent;
339 char __user *start;
340 int ret;
Peter Zijlstra536ebe9ca2014-12-16 16:28:38 +0100341 DEFINE_WAIT_FUNC(wait, woken_wake_function);
Eric Parisa1014f12009-12-17 21:24:26 -0500342
343 start = buf;
344 group = file->private_data;
345
346 pr_debug("%s: group=%p\n", __func__, group);
347
Peter Zijlstra536ebe9ca2014-12-16 16:28:38 +0100348 add_wait_queue(&group->notification_waitq, &wait);
Eric Parisa1014f12009-12-17 21:24:26 -0500349 while (1) {
Eric Parisa1014f12009-12-17 21:24:26 -0500350 kevent = get_one_event(group, count);
Jan Karad8aaab42014-04-03 14:46:35 -0700351 if (IS_ERR(kevent)) {
Eric Parisa1014f12009-12-17 21:24:26 -0500352 ret = PTR_ERR(kevent);
Jan Karad8aaab42014-04-03 14:46:35 -0700353 break;
354 }
355
356 if (!kevent) {
357 ret = -EAGAIN;
358 if (file->f_flags & O_NONBLOCK)
Eric Parisa1014f12009-12-17 21:24:26 -0500359 break;
Jan Karad8aaab42014-04-03 14:46:35 -0700360
361 ret = -ERESTARTSYS;
362 if (signal_pending(current))
Eric Parisa1014f12009-12-17 21:24:26 -0500363 break;
Jan Karad8aaab42014-04-03 14:46:35 -0700364
365 if (start != buf)
366 break;
Peter Zijlstra536ebe9ca2014-12-16 16:28:38 +0100367
368 wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
Eric Parisa1014f12009-12-17 21:24:26 -0500369 continue;
370 }
371
Kees Cook5b03a472018-12-04 15:44:46 -0800372 ret = copy_event_to_user(group, kevent, buf, count);
Amir Goldstein4ff33aa2017-04-25 14:29:35 +0300373 if (unlikely(ret == -EOPENSTALE)) {
374 /*
375 * We cannot report events with stale fd so drop it.
376 * Setting ret to 0 will continue the event loop and
377 * do the right thing if there are no more events to
378 * read (i.e. return bytes read, -EAGAIN or wait).
379 */
380 ret = 0;
381 }
382
Jan Karad8aaab42014-04-03 14:46:35 -0700383 /*
384 * Permission events get queued to wait for response. Other
385 * events can be destroyed now.
386 */
Amir Goldsteina0a92d22019-01-10 19:04:31 +0200387 if (!fanotify_is_perm_event(FANOTIFY_E(kevent)->mask)) {
Jan Karad8aaab42014-04-03 14:46:35 -0700388 fsnotify_destroy_event(group, kevent);
Jan Karad5078162014-04-03 14:46:36 -0700389 } else {
Amir Goldstein4ff33aa2017-04-25 14:29:35 +0300390 if (ret <= 0) {
Jan Kara40873282019-01-08 14:02:44 +0100391 spin_lock(&group->notification_lock);
392 finish_permission_event(group,
393 FANOTIFY_PE(kevent), FAN_DENY);
Jan Karad5078162014-04-03 14:46:36 -0700394 wake_up(&group->fanotify_data.access_waitq);
Amir Goldstein4ff33aa2017-04-25 14:29:35 +0300395 } else {
396 spin_lock(&group->notification_lock);
397 list_add_tail(&kevent->list,
398 &group->fanotify_data.access_list);
399 spin_unlock(&group->notification_lock);
Jan Karad5078162014-04-03 14:46:36 -0700400 }
Jan Karad5078162014-04-03 14:46:36 -0700401 }
Amir Goldstein4ff33aa2017-04-25 14:29:35 +0300402 if (ret < 0)
403 break;
Jan Karad8aaab42014-04-03 14:46:35 -0700404 buf += ret;
405 count -= ret;
Eric Parisa1014f12009-12-17 21:24:26 -0500406 }
Peter Zijlstra536ebe9ca2014-12-16 16:28:38 +0100407 remove_wait_queue(&group->notification_waitq, &wait);
Eric Parisa1014f12009-12-17 21:24:26 -0500408
Eric Parisa1014f12009-12-17 21:24:26 -0500409 if (start != buf && ret != -EFAULT)
410 ret = buf - start;
411 return ret;
412}
413
Eric Parisb2d87902009-12-17 21:24:34 -0500414static ssize_t fanotify_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
415{
Eric Parisb2d87902009-12-17 21:24:34 -0500416 struct fanotify_response response = { .fd = -1, .response = -1 };
417 struct fsnotify_group *group;
418 int ret;
419
Miklos Szeredi6685df32017-10-30 21:14:56 +0100420 if (!IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS))
421 return -EINVAL;
422
Eric Parisb2d87902009-12-17 21:24:34 -0500423 group = file->private_data;
424
425 if (count > sizeof(response))
426 count = sizeof(response);
427
428 pr_debug("%s: group=%p count=%zu\n", __func__, group, count);
429
430 if (copy_from_user(&response, buf, count))
431 return -EFAULT;
432
433 ret = process_access_response(group, &response);
434 if (ret < 0)
435 count = ret;
436
437 return count;
Eric Parisb2d87902009-12-17 21:24:34 -0500438}
439
Eric Paris52c923d2009-12-17 21:24:26 -0500440static int fanotify_release(struct inode *ignored, struct file *file)
441{
442 struct fsnotify_group *group = file->private_data;
Jan Karaca6f8692019-01-09 13:21:01 +0100443 struct fanotify_perm_event *event;
Jan Kara96d41012016-09-19 14:44:30 -0700444 struct fsnotify_event *fsn_event;
Andrew Morton19ba54f2010-10-28 17:21:59 -0400445
Jan Kara5838d442014-08-06 16:03:28 -0700446 /*
Jan Kara96d41012016-09-19 14:44:30 -0700447 * Stop new events from arriving in the notification queue. since
448 * userspace cannot use fanotify fd anymore, no event can enter or
449 * leave access_list by now either.
450 */
451 fsnotify_group_stop_queueing(group);
452
453 /*
454 * Process all permission events on access_list and notification queue
455 * and simulate reply from userspace.
Jan Kara5838d442014-08-06 16:03:28 -0700456 */
Jan Kara073f6552016-10-07 16:56:55 -0700457 spin_lock(&group->notification_lock);
Jan Karaca6f8692019-01-09 13:21:01 +0100458 while (!list_empty(&group->fanotify_data.access_list)) {
459 event = list_first_entry(&group->fanotify_data.access_list,
460 struct fanotify_perm_event, fae.fse.list);
Jan Karaf0834412014-04-03 14:46:33 -0700461 list_del_init(&event->fae.fse.list);
Jan Kara40873282019-01-08 14:02:44 +0100462 finish_permission_event(group, event, FAN_ALLOW);
463 spin_lock(&group->notification_lock);
Eric Paris2eebf582010-08-18 12:25:50 -0400464 }
Eric Paris2eebf582010-08-18 12:25:50 -0400465
Jan Kara5838d442014-08-06 16:03:28 -0700466 /*
Jan Kara96d41012016-09-19 14:44:30 -0700467 * Destroy all non-permission events. For permission events just
468 * dequeue them and set the response. They will be freed once the
469 * response is consumed and fanotify_get_response() returns.
Jan Kara5838d442014-08-06 16:03:28 -0700470 */
Jan Kara96d41012016-09-19 14:44:30 -0700471 while (!fsnotify_notify_queue_is_empty(group)) {
472 fsn_event = fsnotify_remove_first_event(group);
Amir Goldsteina0a92d22019-01-10 19:04:31 +0200473 if (!(FANOTIFY_E(fsn_event)->mask & FANOTIFY_PERM_EVENTS)) {
Jan Karac21dbe22016-10-07 16:56:52 -0700474 spin_unlock(&group->notification_lock);
Jan Kara96d41012016-09-19 14:44:30 -0700475 fsnotify_destroy_event(group, fsn_event);
Miklos Szeredi6685df32017-10-30 21:14:56 +0100476 } else {
Jan Kara40873282019-01-08 14:02:44 +0100477 finish_permission_event(group, FANOTIFY_PE(fsn_event),
478 FAN_ALLOW);
Miklos Szeredi6685df32017-10-30 21:14:56 +0100479 }
Jan Kara40873282019-01-08 14:02:44 +0100480 spin_lock(&group->notification_lock);
Jan Kara96d41012016-09-19 14:44:30 -0700481 }
Jan Karac21dbe22016-10-07 16:56:52 -0700482 spin_unlock(&group->notification_lock);
Jan Kara96d41012016-09-19 14:44:30 -0700483
484 /* Response for all permission events it set, wakeup waiters */
Eric Paris2eebf582010-08-18 12:25:50 -0400485 wake_up(&group->fanotify_data.access_waitq);
Eric Paris0a6b6bd2011-10-14 17:43:39 -0400486
Eric Paris52c923d2009-12-17 21:24:26 -0500487 /* matches the fanotify_init->fsnotify_alloc_group */
Lino Sanfilippod8153d42011-06-14 17:29:45 +0200488 fsnotify_destroy_group(group);
Eric Paris52c923d2009-12-17 21:24:26 -0500489
490 return 0;
491}
492
Eric Parisa1014f12009-12-17 21:24:26 -0500493static long fanotify_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
494{
495 struct fsnotify_group *group;
Jan Kara7053aee2014-01-21 15:48:14 -0800496 struct fsnotify_event *fsn_event;
Eric Parisa1014f12009-12-17 21:24:26 -0500497 void __user *p;
498 int ret = -ENOTTY;
499 size_t send_len = 0;
500
501 group = file->private_data;
502
503 p = (void __user *) arg;
504
505 switch (cmd) {
506 case FIONREAD:
Jan Karac21dbe22016-10-07 16:56:52 -0700507 spin_lock(&group->notification_lock);
Jan Kara7053aee2014-01-21 15:48:14 -0800508 list_for_each_entry(fsn_event, &group->notification_list, list)
Eric Parisa1014f12009-12-17 21:24:26 -0500509 send_len += FAN_EVENT_METADATA_LEN;
Jan Karac21dbe22016-10-07 16:56:52 -0700510 spin_unlock(&group->notification_lock);
Eric Parisa1014f12009-12-17 21:24:26 -0500511 ret = put_user(send_len, (int __user *) p);
512 break;
513 }
514
515 return ret;
516}
517
Eric Paris52c923d2009-12-17 21:24:26 -0500518static const struct file_operations fanotify_fops = {
Cyrill Gorcunovbe771962012-12-17 16:05:12 -0800519 .show_fdinfo = fanotify_show_fdinfo,
Eric Parisa1014f12009-12-17 21:24:26 -0500520 .poll = fanotify_poll,
521 .read = fanotify_read,
Eric Parisb2d87902009-12-17 21:24:34 -0500522 .write = fanotify_write,
Eric Paris52c923d2009-12-17 21:24:26 -0500523 .fasync = NULL,
524 .release = fanotify_release,
Eric Parisa1014f12009-12-17 21:24:26 -0500525 .unlocked_ioctl = fanotify_ioctl,
526 .compat_ioctl = fanotify_ioctl,
Arnd Bergmann6038f372010-08-15 18:52:59 +0200527 .llseek = noop_llseek,
Eric Paris52c923d2009-12-17 21:24:26 -0500528};
529
Eric Paris2a3edf82009-12-17 21:24:26 -0500530static int fanotify_find_path(int dfd, const char __user *filename,
Aaron Goidelac5656d2019-08-12 11:20:00 -0400531 struct path *path, unsigned int flags, __u64 mask,
532 unsigned int obj_type)
Eric Paris2a3edf82009-12-17 21:24:26 -0500533{
534 int ret;
535
536 pr_debug("%s: dfd=%d filename=%p flags=%x\n", __func__,
537 dfd, filename, flags);
538
539 if (filename == NULL) {
Al Viro2903ff02012-08-28 12:52:22 -0400540 struct fd f = fdget(dfd);
Eric Paris2a3edf82009-12-17 21:24:26 -0500541
542 ret = -EBADF;
Al Viro2903ff02012-08-28 12:52:22 -0400543 if (!f.file)
Eric Paris2a3edf82009-12-17 21:24:26 -0500544 goto out;
545
546 ret = -ENOTDIR;
547 if ((flags & FAN_MARK_ONLYDIR) &&
Al Viro496ad9a2013-01-23 17:07:38 -0500548 !(S_ISDIR(file_inode(f.file)->i_mode))) {
Al Viro2903ff02012-08-28 12:52:22 -0400549 fdput(f);
Eric Paris2a3edf82009-12-17 21:24:26 -0500550 goto out;
551 }
552
Al Viro2903ff02012-08-28 12:52:22 -0400553 *path = f.file->f_path;
Eric Paris2a3edf82009-12-17 21:24:26 -0500554 path_get(path);
Al Viro2903ff02012-08-28 12:52:22 -0400555 fdput(f);
Eric Paris2a3edf82009-12-17 21:24:26 -0500556 } else {
557 unsigned int lookup_flags = 0;
558
559 if (!(flags & FAN_MARK_DONT_FOLLOW))
560 lookup_flags |= LOOKUP_FOLLOW;
561 if (flags & FAN_MARK_ONLYDIR)
562 lookup_flags |= LOOKUP_DIRECTORY;
563
564 ret = user_path_at(dfd, filename, lookup_flags, path);
565 if (ret)
566 goto out;
567 }
568
569 /* you can only watch an inode if you have read permissions on it */
570 ret = inode_permission(path->dentry->d_inode, MAY_READ);
Aaron Goidelac5656d2019-08-12 11:20:00 -0400571 if (ret) {
572 path_put(path);
573 goto out;
574 }
575
576 ret = security_path_notify(path, mask, obj_type);
Eric Paris2a3edf82009-12-17 21:24:26 -0500577 if (ret)
578 path_put(path);
Aaron Goidelac5656d2019-08-12 11:20:00 -0400579
Eric Paris2a3edf82009-12-17 21:24:26 -0500580out:
581 return ret;
582}
583
Eric Parisb9e4e3b2009-12-17 21:24:33 -0500584static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
585 __u32 mask,
Lino Sanfilippo6dfbd142011-06-14 17:29:49 +0200586 unsigned int flags,
587 int *destroy)
Andreas Gruenbacher088b09b2009-12-17 21:24:28 -0500588{
Lino Sanfilippod2c18742015-02-10 14:08:24 -0800589 __u32 oldmask = 0;
Andreas Gruenbacher088b09b2009-12-17 21:24:28 -0500590
591 spin_lock(&fsn_mark->lock);
Eric Parisb9e4e3b2009-12-17 21:24:33 -0500592 if (!(flags & FAN_MARK_IGNORED_MASK)) {
593 oldmask = fsn_mark->mask;
Amir Goldsteina72fd222018-10-04 00:25:34 +0300594 fsn_mark->mask &= ~mask;
Eric Parisb9e4e3b2009-12-17 21:24:33 -0500595 } else {
Amir Goldsteina72fd222018-10-04 00:25:34 +0300596 fsn_mark->ignored_mask &= ~mask;
Eric Parisb9e4e3b2009-12-17 21:24:33 -0500597 }
Lino Sanfilippoa1184492015-02-10 14:08:21 -0800598 *destroy = !(fsn_mark->mask | fsn_mark->ignored_mask);
Andreas Gruenbacher088b09b2009-12-17 21:24:28 -0500599 spin_unlock(&fsn_mark->lock);
600
Andreas Gruenbacher088b09b2009-12-17 21:24:28 -0500601 return mask & oldmask;
602}
603
Amir Goldsteineaa2c6b2018-06-23 17:54:51 +0300604static int fanotify_remove_mark(struct fsnotify_group *group,
605 fsnotify_connp_t *connp, __u32 mask,
606 unsigned int flags)
Eric Paris88826272009-12-17 21:24:28 -0500607{
608 struct fsnotify_mark *fsn_mark = NULL;
Andreas Gruenbacher088b09b2009-12-17 21:24:28 -0500609 __u32 removed;
Lino Sanfilippo6dfbd142011-06-14 17:29:49 +0200610 int destroy_mark;
Eric Paris88826272009-12-17 21:24:28 -0500611
Lino Sanfilippo7b185272013-07-08 15:59:42 -0700612 mutex_lock(&group->mark_mutex);
Amir Goldsteineaa2c6b2018-06-23 17:54:51 +0300613 fsn_mark = fsnotify_find_mark(connp, group);
Lino Sanfilippo7b185272013-07-08 15:59:42 -0700614 if (!fsn_mark) {
615 mutex_unlock(&group->mark_mutex);
Eric Paris88826272009-12-17 21:24:28 -0500616 return -ENOENT;
Lino Sanfilippo7b185272013-07-08 15:59:42 -0700617 }
Eric Paris88826272009-12-17 21:24:28 -0500618
Lino Sanfilippo6dfbd142011-06-14 17:29:49 +0200619 removed = fanotify_mark_remove_from_mask(fsn_mark, mask, flags,
620 &destroy_mark);
Amir Goldstein3ac70bf2018-06-23 17:54:50 +0300621 if (removed & fsnotify_conn_mask(fsn_mark->connector))
622 fsnotify_recalc_mask(fsn_mark->connector);
Lino Sanfilippo6dfbd142011-06-14 17:29:49 +0200623 if (destroy_mark)
Jan Kara4712e7222015-09-04 15:43:12 -0700624 fsnotify_detach_mark(fsn_mark);
Lino Sanfilippo7b185272013-07-08 15:59:42 -0700625 mutex_unlock(&group->mark_mutex);
Jan Kara4712e7222015-09-04 15:43:12 -0700626 if (destroy_mark)
627 fsnotify_free_mark(fsn_mark);
Lino Sanfilippo7b185272013-07-08 15:59:42 -0700628
Jan Karab1362ed2016-12-21 16:28:45 +0100629 /* matches the fsnotify_find_mark() */
Eric Paris2a3edf82009-12-17 21:24:26 -0500630 fsnotify_put_mark(fsn_mark);
Eric Paris2a3edf82009-12-17 21:24:26 -0500631 return 0;
632}
633
Amir Goldsteineaa2c6b2018-06-23 17:54:51 +0300634static int fanotify_remove_vfsmount_mark(struct fsnotify_group *group,
635 struct vfsmount *mnt, __u32 mask,
636 unsigned int flags)
637{
638 return fanotify_remove_mark(group, &real_mount(mnt)->mnt_fsnotify_marks,
639 mask, flags);
640}
641
Amir Goldsteind54f4fb2018-09-01 10:41:13 +0300642static int fanotify_remove_sb_mark(struct fsnotify_group *group,
643 struct super_block *sb, __u32 mask,
644 unsigned int flags)
645{
646 return fanotify_remove_mark(group, &sb->s_fsnotify_marks, mask, flags);
647}
648
Amir Goldsteineaa2c6b2018-06-23 17:54:51 +0300649static int fanotify_remove_inode_mark(struct fsnotify_group *group,
650 struct inode *inode, __u32 mask,
651 unsigned int flags)
652{
653 return fanotify_remove_mark(group, &inode->i_fsnotify_marks, mask,
654 flags);
655}
656
Eric Parisb9e4e3b2009-12-17 21:24:33 -0500657static __u32 fanotify_mark_add_to_mask(struct fsnotify_mark *fsn_mark,
658 __u32 mask,
659 unsigned int flags)
Andreas Gruenbacher912ee39462009-12-17 21:24:28 -0500660{
Eric Paris192ca4d2010-10-28 17:21:59 -0400661 __u32 oldmask = -1;
Andreas Gruenbacher912ee39462009-12-17 21:24:28 -0500662
663 spin_lock(&fsn_mark->lock);
Eric Parisb9e4e3b2009-12-17 21:24:33 -0500664 if (!(flags & FAN_MARK_IGNORED_MASK)) {
665 oldmask = fsn_mark->mask;
Amir Goldsteina72fd222018-10-04 00:25:34 +0300666 fsn_mark->mask |= mask;
Eric Parisb9e4e3b2009-12-17 21:24:33 -0500667 } else {
Amir Goldsteina72fd222018-10-04 00:25:34 +0300668 fsn_mark->ignored_mask |= mask;
Eric Parisc9778a92009-12-17 21:24:33 -0500669 if (flags & FAN_MARK_IGNORED_SURV_MODIFY)
670 fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY;
Eric Parisb9e4e3b2009-12-17 21:24:33 -0500671 }
Andreas Gruenbacher912ee39462009-12-17 21:24:28 -0500672 spin_unlock(&fsn_mark->lock);
673
674 return mask & ~oldmask;
675}
676
Lino Sanfilippo5e9c070c2013-07-08 15:59:43 -0700677static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
Amir Goldsteinb812a9f2018-06-23 17:54:48 +0300678 fsnotify_connp_t *connp,
Amir Goldstein77115222019-01-10 19:04:37 +0200679 unsigned int type,
680 __kernel_fsid_t *fsid)
Lino Sanfilippo5e9c070c2013-07-08 15:59:43 -0700681{
682 struct fsnotify_mark *mark;
683 int ret;
684
685 if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks)
686 return ERR_PTR(-ENOSPC);
687
688 mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL);
689 if (!mark)
690 return ERR_PTR(-ENOMEM);
691
Jan Kara054c6362016-12-21 18:06:12 +0100692 fsnotify_init_mark(mark, group);
Amir Goldstein77115222019-01-10 19:04:37 +0200693 ret = fsnotify_add_mark_locked(mark, connp, type, 0, fsid);
Lino Sanfilippo5e9c070c2013-07-08 15:59:43 -0700694 if (ret) {
695 fsnotify_put_mark(mark);
696 return ERR_PTR(ret);
697 }
698
699 return mark;
700}
701
702
Amir Goldsteineaa2c6b2018-06-23 17:54:51 +0300703static int fanotify_add_mark(struct fsnotify_group *group,
704 fsnotify_connp_t *connp, unsigned int type,
Amir Goldstein77115222019-01-10 19:04:37 +0200705 __u32 mask, unsigned int flags,
706 __kernel_fsid_t *fsid)
Eric Paris2a3edf82009-12-17 21:24:26 -0500707{
708 struct fsnotify_mark *fsn_mark;
Andreas Gruenbacher912ee39462009-12-17 21:24:28 -0500709 __u32 added;
Eric Paris2a3edf82009-12-17 21:24:26 -0500710
Lino Sanfilippo7b185272013-07-08 15:59:42 -0700711 mutex_lock(&group->mark_mutex);
Amir Goldsteinb812a9f2018-06-23 17:54:48 +0300712 fsn_mark = fsnotify_find_mark(connp, group);
Eric Paris88826272009-12-17 21:24:28 -0500713 if (!fsn_mark) {
Amir Goldstein77115222019-01-10 19:04:37 +0200714 fsn_mark = fanotify_add_new_mark(group, connp, type, fsid);
Lino Sanfilippo5e9c070c2013-07-08 15:59:43 -0700715 if (IS_ERR(fsn_mark)) {
Lino Sanfilippo7b185272013-07-08 15:59:42 -0700716 mutex_unlock(&group->mark_mutex);
Lino Sanfilippo5e9c070c2013-07-08 15:59:43 -0700717 return PTR_ERR(fsn_mark);
Lino Sanfilippo7b185272013-07-08 15:59:42 -0700718 }
Eric Paris88826272009-12-17 21:24:28 -0500719 }
Eric Parisb9e4e3b2009-12-17 21:24:33 -0500720 added = fanotify_mark_add_to_mask(fsn_mark, mask, flags);
Amir Goldstein3ac70bf2018-06-23 17:54:50 +0300721 if (added & ~fsnotify_conn_mask(fsn_mark->connector))
722 fsnotify_recalc_mask(fsn_mark->connector);
Jan Karac9747642016-12-14 13:53:46 +0100723 mutex_unlock(&group->mark_mutex);
Lino Sanfilippo5e9c070c2013-07-08 15:59:43 -0700724
Lino Sanfilippofa218ab2010-11-09 18:18:16 +0100725 fsnotify_put_mark(fsn_mark);
Lino Sanfilippo5e9c070c2013-07-08 15:59:43 -0700726 return 0;
Eric Paris88826272009-12-17 21:24:28 -0500727}
728
Amir Goldsteineaa2c6b2018-06-23 17:54:51 +0300729static int fanotify_add_vfsmount_mark(struct fsnotify_group *group,
730 struct vfsmount *mnt, __u32 mask,
Amir Goldstein77115222019-01-10 19:04:37 +0200731 unsigned int flags, __kernel_fsid_t *fsid)
Amir Goldsteineaa2c6b2018-06-23 17:54:51 +0300732{
733 return fanotify_add_mark(group, &real_mount(mnt)->mnt_fsnotify_marks,
Amir Goldstein77115222019-01-10 19:04:37 +0200734 FSNOTIFY_OBJ_TYPE_VFSMOUNT, mask, flags, fsid);
Amir Goldsteineaa2c6b2018-06-23 17:54:51 +0300735}
736
Amir Goldsteind54f4fb2018-09-01 10:41:13 +0300737static int fanotify_add_sb_mark(struct fsnotify_group *group,
Amir Goldstein77115222019-01-10 19:04:37 +0200738 struct super_block *sb, __u32 mask,
739 unsigned int flags, __kernel_fsid_t *fsid)
Amir Goldsteind54f4fb2018-09-01 10:41:13 +0300740{
741 return fanotify_add_mark(group, &sb->s_fsnotify_marks,
Amir Goldstein77115222019-01-10 19:04:37 +0200742 FSNOTIFY_OBJ_TYPE_SB, mask, flags, fsid);
Amir Goldsteind54f4fb2018-09-01 10:41:13 +0300743}
744
Andreas Gruenbacher52202df2009-12-17 21:24:28 -0500745static int fanotify_add_inode_mark(struct fsnotify_group *group,
Eric Parisb9e4e3b2009-12-17 21:24:33 -0500746 struct inode *inode, __u32 mask,
Amir Goldstein77115222019-01-10 19:04:37 +0200747 unsigned int flags, __kernel_fsid_t *fsid)
Eric Paris88826272009-12-17 21:24:28 -0500748{
Eric Paris88826272009-12-17 21:24:28 -0500749 pr_debug("%s: group=%p inode=%p\n", __func__, group, inode);
Eric Paris2a3edf82009-12-17 21:24:26 -0500750
Eric Paris5322a592010-10-28 17:21:57 -0400751 /*
752 * If some other task has this inode open for write we should not add
753 * an ignored mark, unless that ignored mark is supposed to survive
754 * modification changes anyway.
755 */
756 if ((flags & FAN_MARK_IGNORED_MASK) &&
757 !(flags & FAN_MARK_IGNORED_SURV_MODIFY) &&
Nikolay Borisovac9498d2018-12-11 10:27:23 +0200758 inode_is_open_for_write(inode))
Eric Paris5322a592010-10-28 17:21:57 -0400759 return 0;
760
Amir Goldsteineaa2c6b2018-06-23 17:54:51 +0300761 return fanotify_add_mark(group, &inode->i_fsnotify_marks,
Amir Goldstein77115222019-01-10 19:04:37 +0200762 FSNOTIFY_OBJ_TYPE_INODE, mask, flags, fsid);
Eric Paris88826272009-12-17 21:24:28 -0500763}
Eric Paris2a3edf82009-12-17 21:24:26 -0500764
Eric Paris52c923d2009-12-17 21:24:26 -0500765/* fanotify syscalls */
Eric Paris08ae8932010-05-27 09:41:40 -0400766SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
Eric Paris11637e42009-12-17 21:24:25 -0500767{
Eric Paris52c923d2009-12-17 21:24:26 -0500768 struct fsnotify_group *group;
769 int f_flags, fd;
Eric Paris4afeff82010-10-28 17:21:58 -0400770 struct user_struct *user;
Amir Goldstein33913992019-01-10 19:04:32 +0200771 struct fanotify_event *oevent;
Eric Paris52c923d2009-12-17 21:24:26 -0500772
Amir Goldstein96a71f22018-09-21 21:20:30 +0300773 pr_debug("%s: flags=%x event_f_flags=%x\n",
774 __func__, flags, event_f_flags);
Eric Paris52c923d2009-12-17 21:24:26 -0500775
Eric Paris52c923d2009-12-17 21:24:26 -0500776 if (!capable(CAP_SYS_ADMIN))
Andreas Gruenbachera2f13ad2010-08-24 12:58:54 +0200777 return -EPERM;
Eric Paris52c923d2009-12-17 21:24:26 -0500778
Steve Grubbde8cd832017-10-02 20:21:39 -0400779#ifdef CONFIG_AUDITSYSCALL
Amir Goldstein23c9dee2018-10-04 00:25:35 +0300780 if (flags & ~(FANOTIFY_INIT_FLAGS | FAN_ENABLE_AUDIT))
Steve Grubbde8cd832017-10-02 20:21:39 -0400781#else
Amir Goldstein23c9dee2018-10-04 00:25:35 +0300782 if (flags & ~FANOTIFY_INIT_FLAGS)
Steve Grubbde8cd832017-10-02 20:21:39 -0400783#endif
Eric Paris52c923d2009-12-17 21:24:26 -0500784 return -EINVAL;
785
Heinrich Schuchardt48149e92014-06-04 16:05:44 -0700786 if (event_f_flags & ~FANOTIFY_INIT_ALL_EVENT_F_BITS)
787 return -EINVAL;
788
789 switch (event_f_flags & O_ACCMODE) {
790 case O_RDONLY:
791 case O_RDWR:
792 case O_WRONLY:
793 break;
794 default:
795 return -EINVAL;
796 }
797
Amir Goldsteina8b13aa2019-01-10 19:04:36 +0200798 if ((flags & FAN_REPORT_FID) &&
799 (flags & FANOTIFY_CLASS_BITS) != FAN_CLASS_NOTIF)
800 return -EINVAL;
801
Eric Paris4afeff82010-10-28 17:21:58 -0400802 user = get_current_user();
803 if (atomic_read(&user->fanotify_listeners) > FANOTIFY_DEFAULT_MAX_LISTENERS) {
804 free_uid(user);
805 return -EMFILE;
806 }
807
Eric Parisb2d87902009-12-17 21:24:34 -0500808 f_flags = O_RDWR | FMODE_NONOTIFY;
Eric Paris52c923d2009-12-17 21:24:26 -0500809 if (flags & FAN_CLOEXEC)
810 f_flags |= O_CLOEXEC;
811 if (flags & FAN_NONBLOCK)
812 f_flags |= O_NONBLOCK;
813
814 /* fsnotify_alloc_group takes a ref. Dropped in fanotify_release */
815 group = fsnotify_alloc_group(&fanotify_fsnotify_ops);
Eric Paris26379192010-11-23 23:48:26 -0500816 if (IS_ERR(group)) {
817 free_uid(user);
Eric Paris52c923d2009-12-17 21:24:26 -0500818 return PTR_ERR(group);
Eric Paris26379192010-11-23 23:48:26 -0500819 }
Eric Paris52c923d2009-12-17 21:24:26 -0500820
Eric Paris4afeff82010-10-28 17:21:58 -0400821 group->fanotify_data.user = user;
Amir Goldstein96a71f22018-09-21 21:20:30 +0300822 group->fanotify_data.flags = flags;
Eric Paris4afeff82010-10-28 17:21:58 -0400823 atomic_inc(&user->fanotify_listeners);
Shakeel Buttd46eb14b2018-08-17 15:46:39 -0700824 group->memcg = get_mem_cgroup_from_mm(current->mm);
Eric Paris4afeff82010-10-28 17:21:58 -0400825
Amir Goldstein83b535d2019-01-10 19:04:42 +0200826 oevent = fanotify_alloc_event(group, NULL, FS_Q_OVERFLOW, NULL,
827 FSNOTIFY_EVENT_NONE, NULL);
Jan Karaff57cd52014-02-21 19:14:11 +0100828 if (unlikely(!oevent)) {
829 fd = -ENOMEM;
830 goto out_destroy_group;
831 }
832 group->overflow_event = &oevent->fse;
Jan Karaff57cd52014-02-21 19:14:11 +0100833
Will Woods1e2ee492014-05-06 12:50:10 -0700834 if (force_o_largefile())
835 event_f_flags |= O_LARGEFILE;
Eric Paris80af2582010-07-28 10:18:37 -0400836 group->fanotify_data.f_flags = event_f_flags;
Eric Paris9e66e422009-12-17 21:24:34 -0500837 init_waitqueue_head(&group->fanotify_data.access_waitq);
838 INIT_LIST_HEAD(&group->fanotify_data.access_list);
Amir Goldstein23c9dee2018-10-04 00:25:35 +0300839 switch (flags & FANOTIFY_CLASS_BITS) {
Eric Paris4231a232010-10-28 17:21:56 -0400840 case FAN_CLASS_NOTIF:
841 group->priority = FS_PRIO_0;
842 break;
843 case FAN_CLASS_CONTENT:
844 group->priority = FS_PRIO_1;
845 break;
846 case FAN_CLASS_PRE_CONTENT:
847 group->priority = FS_PRIO_2;
848 break;
849 default:
850 fd = -EINVAL;
Lino Sanfilippod8153d42011-06-14 17:29:45 +0200851 goto out_destroy_group;
Eric Paris4231a232010-10-28 17:21:56 -0400852 }
Eric Pariscb2d4292009-12-17 21:24:34 -0500853
Eric Paris5dd03f52010-10-28 17:21:57 -0400854 if (flags & FAN_UNLIMITED_QUEUE) {
855 fd = -EPERM;
856 if (!capable(CAP_SYS_ADMIN))
Lino Sanfilippod8153d42011-06-14 17:29:45 +0200857 goto out_destroy_group;
Eric Paris5dd03f52010-10-28 17:21:57 -0400858 group->max_events = UINT_MAX;
859 } else {
860 group->max_events = FANOTIFY_DEFAULT_MAX_EVENTS;
861 }
Eric Paris2529a0d2010-10-28 17:21:57 -0400862
Eric Parisac7e22d2010-10-28 17:21:58 -0400863 if (flags & FAN_UNLIMITED_MARKS) {
864 fd = -EPERM;
865 if (!capable(CAP_SYS_ADMIN))
Lino Sanfilippod8153d42011-06-14 17:29:45 +0200866 goto out_destroy_group;
Eric Parisac7e22d2010-10-28 17:21:58 -0400867 group->fanotify_data.max_marks = UINT_MAX;
868 } else {
869 group->fanotify_data.max_marks = FANOTIFY_DEFAULT_MAX_MARKS;
870 }
Eric Parise7099d82010-10-28 17:21:57 -0400871
Steve Grubbde8cd832017-10-02 20:21:39 -0400872 if (flags & FAN_ENABLE_AUDIT) {
873 fd = -EPERM;
874 if (!capable(CAP_AUDIT_WRITE))
875 goto out_destroy_group;
Steve Grubbde8cd832017-10-02 20:21:39 -0400876 }
877
Eric Paris52c923d2009-12-17 21:24:26 -0500878 fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags);
879 if (fd < 0)
Lino Sanfilippod8153d42011-06-14 17:29:45 +0200880 goto out_destroy_group;
Eric Paris52c923d2009-12-17 21:24:26 -0500881
882 return fd;
883
Lino Sanfilippod8153d42011-06-14 17:29:45 +0200884out_destroy_group:
885 fsnotify_destroy_group(group);
Eric Paris52c923d2009-12-17 21:24:26 -0500886 return fd;
Eric Paris11637e42009-12-17 21:24:25 -0500887}
Eric Parisbbaa4162009-12-17 21:24:26 -0500888
Amir Goldsteina8b13aa2019-01-10 19:04:36 +0200889/* Check if filesystem can encode a unique fid */
Amir Goldstein73072282019-01-10 19:04:39 +0200890static int fanotify_test_fid(struct path *path, __kernel_fsid_t *fsid)
Amir Goldsteina8b13aa2019-01-10 19:04:36 +0200891{
Amir Goldstein73072282019-01-10 19:04:39 +0200892 __kernel_fsid_t root_fsid;
Amir Goldsteina8b13aa2019-01-10 19:04:36 +0200893 int err;
894
895 /*
896 * Make sure path is not in filesystem with zero fsid (e.g. tmpfs).
897 */
Amir Goldstein73072282019-01-10 19:04:39 +0200898 err = vfs_get_fsid(path->dentry, fsid);
Amir Goldsteina8b13aa2019-01-10 19:04:36 +0200899 if (err)
900 return err;
901
Amir Goldstein73072282019-01-10 19:04:39 +0200902 if (!fsid->val[0] && !fsid->val[1])
Amir Goldsteina8b13aa2019-01-10 19:04:36 +0200903 return -ENODEV;
904
905 /*
906 * Make sure path is not inside a filesystem subvolume (e.g. btrfs)
907 * which uses a different fsid than sb root.
908 */
Amir Goldstein73072282019-01-10 19:04:39 +0200909 err = vfs_get_fsid(path->dentry->d_sb->s_root, &root_fsid);
Amir Goldsteina8b13aa2019-01-10 19:04:36 +0200910 if (err)
911 return err;
912
Amir Goldstein73072282019-01-10 19:04:39 +0200913 if (root_fsid.val[0] != fsid->val[0] ||
914 root_fsid.val[1] != fsid->val[1])
Amir Goldsteina8b13aa2019-01-10 19:04:36 +0200915 return -EXDEV;
916
917 /*
918 * We need to make sure that the file system supports at least
919 * encoding a file handle so user can use name_to_handle_at() to
920 * compare fid returned with event to the file handle of watched
921 * objects. However, name_to_handle_at() requires that the
922 * filesystem also supports decoding file handles.
923 */
924 if (!path->dentry->d_sb->s_export_op ||
925 !path->dentry->d_sb->s_export_op->fh_to_dentry)
926 return -EOPNOTSUPP;
927
928 return 0;
929}
930
Dominik Brodowski183caa32018-03-17 15:06:11 +0100931static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
932 int dfd, const char __user *pathname)
Eric Parisbbaa4162009-12-17 21:24:26 -0500933{
Eric Paris0ff21db2009-12-17 21:24:29 -0500934 struct inode *inode = NULL;
935 struct vfsmount *mnt = NULL;
Eric Paris2a3edf82009-12-17 21:24:26 -0500936 struct fsnotify_group *group;
Al Viro2903ff02012-08-28 12:52:22 -0400937 struct fd f;
Eric Paris2a3edf82009-12-17 21:24:26 -0500938 struct path path;
Amir Goldstein73072282019-01-10 19:04:39 +0200939 __kernel_fsid_t __fsid, *fsid = NULL;
Amir Goldsteinbdd5a462018-10-04 00:25:37 +0300940 u32 valid_mask = FANOTIFY_EVENTS | FANOTIFY_EVENT_FLAGS;
Amir Goldstein23c9dee2018-10-04 00:25:35 +0300941 unsigned int mark_type = flags & FANOTIFY_MARK_TYPE_BITS;
Aaron Goidelac5656d2019-08-12 11:20:00 -0400942 unsigned int obj_type;
Al Viro2903ff02012-08-28 12:52:22 -0400943 int ret;
Eric Paris2a3edf82009-12-17 21:24:26 -0500944
945 pr_debug("%s: fanotify_fd=%d flags=%x dfd=%d pathname=%p mask=%llx\n",
946 __func__, fanotify_fd, flags, dfd, pathname, mask);
947
948 /* we only use the lower 32 bits as of right now. */
949 if (mask & ((__u64)0xffffffff << 32))
950 return -EINVAL;
951
Amir Goldstein23c9dee2018-10-04 00:25:35 +0300952 if (flags & ~FANOTIFY_MARK_FLAGS)
Andreas Gruenbacher88380fe2009-12-17 21:24:29 -0500953 return -EINVAL;
Amir Goldsteind54f4fb2018-09-01 10:41:13 +0300954
955 switch (mark_type) {
956 case FAN_MARK_INODE:
Aaron Goidelac5656d2019-08-12 11:20:00 -0400957 obj_type = FSNOTIFY_OBJ_TYPE_INODE;
958 break;
Amir Goldsteind54f4fb2018-09-01 10:41:13 +0300959 case FAN_MARK_MOUNT:
Aaron Goidelac5656d2019-08-12 11:20:00 -0400960 obj_type = FSNOTIFY_OBJ_TYPE_VFSMOUNT;
961 break;
Amir Goldsteind54f4fb2018-09-01 10:41:13 +0300962 case FAN_MARK_FILESYSTEM:
Aaron Goidelac5656d2019-08-12 11:20:00 -0400963 obj_type = FSNOTIFY_OBJ_TYPE_SB;
Amir Goldsteind54f4fb2018-09-01 10:41:13 +0300964 break;
965 default:
966 return -EINVAL;
967 }
968
Eric Paris4d926042009-12-17 21:24:34 -0500969 switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {
Lino Sanfilippo1734dee2010-11-22 18:46:33 +0100970 case FAN_MARK_ADD: /* fallthrough */
Andreas Gruenbacher88380fe2009-12-17 21:24:29 -0500971 case FAN_MARK_REMOVE:
Lino Sanfilippo1734dee2010-11-22 18:46:33 +0100972 if (!mask)
973 return -EINVAL;
Heinrich Schuchardtcc299a92014-06-04 16:05:43 -0700974 break;
Eric Paris4d926042009-12-17 21:24:34 -0500975 case FAN_MARK_FLUSH:
Amir Goldstein23c9dee2018-10-04 00:25:35 +0300976 if (flags & ~(FANOTIFY_MARK_TYPE_BITS | FAN_MARK_FLUSH))
Heinrich Schuchardtcc299a92014-06-04 16:05:43 -0700977 return -EINVAL;
Andreas Gruenbacher88380fe2009-12-17 21:24:29 -0500978 break;
979 default:
980 return -EINVAL;
981 }
Eric Paris8fcd6522010-10-28 17:21:59 -0400982
Miklos Szeredi6685df32017-10-30 21:14:56 +0100983 if (IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS))
Amir Goldstein23c9dee2018-10-04 00:25:35 +0300984 valid_mask |= FANOTIFY_PERM_EVENTS;
Miklos Szeredi6685df32017-10-30 21:14:56 +0100985
986 if (mask & ~valid_mask)
Eric Paris2a3edf82009-12-17 21:24:26 -0500987 return -EINVAL;
988
Al Viro2903ff02012-08-28 12:52:22 -0400989 f = fdget(fanotify_fd);
990 if (unlikely(!f.file))
Eric Paris2a3edf82009-12-17 21:24:26 -0500991 return -EBADF;
992
993 /* verify that this is indeed an fanotify instance */
994 ret = -EINVAL;
Al Viro2903ff02012-08-28 12:52:22 -0400995 if (unlikely(f.file->f_op != &fanotify_fops))
Eric Paris2a3edf82009-12-17 21:24:26 -0500996 goto fput_and_out;
Al Viro2903ff02012-08-28 12:52:22 -0400997 group = f.file->private_data;
Eric Paris4231a232010-10-28 17:21:56 -0400998
999 /*
1000 * group->priority == FS_PRIO_0 == FAN_CLASS_NOTIF. These are not
1001 * allowed to set permissions events.
1002 */
1003 ret = -EINVAL;
Amir Goldstein23c9dee2018-10-04 00:25:35 +03001004 if (mask & FANOTIFY_PERM_EVENTS &&
Eric Paris4231a232010-10-28 17:21:56 -04001005 group->priority == FS_PRIO_0)
1006 goto fput_and_out;
Eric Paris2a3edf82009-12-17 21:24:26 -05001007
Amir Goldstein235328d2019-01-10 19:04:43 +02001008 /*
1009 * Events with data type inode do not carry enough information to report
1010 * event->fd, so we do not allow setting a mask for inode events unless
1011 * group supports reporting fid.
1012 * inode events are not supported on a mount mark, because they do not
1013 * carry enough information (i.e. path) to be filtered by mount point.
1014 */
1015 if (mask & FANOTIFY_INODE_EVENTS &&
1016 (!FAN_GROUP_FLAG(group, FAN_REPORT_FID) ||
1017 mark_type == FAN_MARK_MOUNT))
1018 goto fput_and_out;
1019
Heinrich Schuchardt0a8dd2d2014-06-04 16:05:40 -07001020 if (flags & FAN_MARK_FLUSH) {
1021 ret = 0;
Amir Goldsteind54f4fb2018-09-01 10:41:13 +03001022 if (mark_type == FAN_MARK_MOUNT)
Heinrich Schuchardt0a8dd2d2014-06-04 16:05:40 -07001023 fsnotify_clear_vfsmount_marks_by_group(group);
Amir Goldsteind54f4fb2018-09-01 10:41:13 +03001024 else if (mark_type == FAN_MARK_FILESYSTEM)
1025 fsnotify_clear_sb_marks_by_group(group);
Heinrich Schuchardt0a8dd2d2014-06-04 16:05:40 -07001026 else
1027 fsnotify_clear_inode_marks_by_group(group);
1028 goto fput_and_out;
1029 }
1030
Aaron Goidelac5656d2019-08-12 11:20:00 -04001031 ret = fanotify_find_path(dfd, pathname, &path, flags,
1032 (mask & ALL_FSNOTIFY_EVENTS), obj_type);
Eric Paris2a3edf82009-12-17 21:24:26 -05001033 if (ret)
1034 goto fput_and_out;
1035
Amir Goldsteina8b13aa2019-01-10 19:04:36 +02001036 if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) {
Amir Goldstein73072282019-01-10 19:04:39 +02001037 ret = fanotify_test_fid(&path, &__fsid);
Amir Goldsteina8b13aa2019-01-10 19:04:36 +02001038 if (ret)
1039 goto path_put_and_out;
Amir Goldstein77115222019-01-10 19:04:37 +02001040
Amir Goldstein73072282019-01-10 19:04:39 +02001041 fsid = &__fsid;
Amir Goldsteina8b13aa2019-01-10 19:04:36 +02001042 }
1043
Eric Paris2a3edf82009-12-17 21:24:26 -05001044 /* inode held in place by reference to path; group by fget on fd */
Amir Goldsteind54f4fb2018-09-01 10:41:13 +03001045 if (mark_type == FAN_MARK_INODE)
Eric Paris0ff21db2009-12-17 21:24:29 -05001046 inode = path.dentry->d_inode;
1047 else
1048 mnt = path.mnt;
Eric Paris2a3edf82009-12-17 21:24:26 -05001049
1050 /* create/update an inode mark */
Heinrich Schuchardt0a8dd2d2014-06-04 16:05:40 -07001051 switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE)) {
Andreas Gruenbacherc6223f42009-12-17 21:24:28 -05001052 case FAN_MARK_ADD:
Amir Goldsteind54f4fb2018-09-01 10:41:13 +03001053 if (mark_type == FAN_MARK_MOUNT)
Amir Goldstein77115222019-01-10 19:04:37 +02001054 ret = fanotify_add_vfsmount_mark(group, mnt, mask,
1055 flags, fsid);
Amir Goldsteind54f4fb2018-09-01 10:41:13 +03001056 else if (mark_type == FAN_MARK_FILESYSTEM)
Amir Goldstein77115222019-01-10 19:04:37 +02001057 ret = fanotify_add_sb_mark(group, mnt->mnt_sb, mask,
1058 flags, fsid);
Eric Paris0ff21db2009-12-17 21:24:29 -05001059 else
Amir Goldstein77115222019-01-10 19:04:37 +02001060 ret = fanotify_add_inode_mark(group, inode, mask,
1061 flags, fsid);
Andreas Gruenbacherc6223f42009-12-17 21:24:28 -05001062 break;
1063 case FAN_MARK_REMOVE:
Amir Goldsteind54f4fb2018-09-01 10:41:13 +03001064 if (mark_type == FAN_MARK_MOUNT)
Amir Goldstein77115222019-01-10 19:04:37 +02001065 ret = fanotify_remove_vfsmount_mark(group, mnt, mask,
1066 flags);
Amir Goldsteind54f4fb2018-09-01 10:41:13 +03001067 else if (mark_type == FAN_MARK_FILESYSTEM)
Amir Goldstein77115222019-01-10 19:04:37 +02001068 ret = fanotify_remove_sb_mark(group, mnt->mnt_sb, mask,
1069 flags);
Andreas Gruenbacherf3640192009-12-17 21:24:29 -05001070 else
Amir Goldstein77115222019-01-10 19:04:37 +02001071 ret = fanotify_remove_inode_mark(group, inode, mask,
1072 flags);
Andreas Gruenbacherc6223f42009-12-17 21:24:28 -05001073 break;
1074 default:
1075 ret = -EINVAL;
1076 }
Eric Paris2a3edf82009-12-17 21:24:26 -05001077
Amir Goldsteina8b13aa2019-01-10 19:04:36 +02001078path_put_and_out:
Eric Paris2a3edf82009-12-17 21:24:26 -05001079 path_put(&path);
1080fput_and_out:
Al Viro2903ff02012-08-28 12:52:22 -04001081 fdput(f);
Eric Paris2a3edf82009-12-17 21:24:26 -05001082 return ret;
Eric Parisbbaa4162009-12-17 21:24:26 -05001083}
Eric Paris2a3edf82009-12-17 21:24:26 -05001084
Dominik Brodowski183caa32018-03-17 15:06:11 +01001085SYSCALL_DEFINE5(fanotify_mark, int, fanotify_fd, unsigned int, flags,
1086 __u64, mask, int, dfd,
1087 const char __user *, pathname)
1088{
1089 return do_fanotify_mark(fanotify_fd, flags, mask, dfd, pathname);
1090}
1091
Al Viro91c2e0b2013-03-05 20:10:59 -05001092#ifdef CONFIG_COMPAT
1093COMPAT_SYSCALL_DEFINE6(fanotify_mark,
1094 int, fanotify_fd, unsigned int, flags,
1095 __u32, mask0, __u32, mask1, int, dfd,
1096 const char __user *, pathname)
1097{
Dominik Brodowski183caa32018-03-17 15:06:11 +01001098 return do_fanotify_mark(fanotify_fd, flags,
Al Viro91c2e0b2013-03-05 20:10:59 -05001099#ifdef __BIG_ENDIAN
Al Viro91c2e0b2013-03-05 20:10:59 -05001100 ((__u64)mask0 << 32) | mask1,
Heiko Carstens592f6b82014-01-27 17:07:19 -08001101#else
1102 ((__u64)mask1 << 32) | mask0,
Al Viro91c2e0b2013-03-05 20:10:59 -05001103#endif
1104 dfd, pathname);
1105}
1106#endif
1107
Eric Paris2a3edf82009-12-17 21:24:26 -05001108/*
Justin P. Mattockae0e47f2011-03-01 15:06:02 +01001109 * fanotify_user_setup - Our initialization function. Note that we cannot return
Eric Paris2a3edf82009-12-17 21:24:26 -05001110 * error because we have compiled-in VFS hooks. So an (unlikely) failure here
1111 * must result in panic().
1112 */
1113static int __init fanotify_user_setup(void)
1114{
Amir Goldsteina8b13aa2019-01-10 19:04:36 +02001115 BUILD_BUG_ON(HWEIGHT32(FANOTIFY_INIT_FLAGS) != 8);
Amir Goldsteinbdd5a462018-10-04 00:25:37 +03001116 BUILD_BUG_ON(HWEIGHT32(FANOTIFY_MARK_FLAGS) != 9);
1117
Shakeel Buttd46eb14b2018-08-17 15:46:39 -07001118 fanotify_mark_cache = KMEM_CACHE(fsnotify_mark,
1119 SLAB_PANIC|SLAB_ACCOUNT);
Amir Goldstein33913992019-01-10 19:04:32 +02001120 fanotify_event_cachep = KMEM_CACHE(fanotify_event, SLAB_PANIC);
Miklos Szeredi6685df32017-10-30 21:14:56 +01001121 if (IS_ENABLED(CONFIG_FANOTIFY_ACCESS_PERMISSIONS)) {
1122 fanotify_perm_event_cachep =
Amir Goldstein33913992019-01-10 19:04:32 +02001123 KMEM_CACHE(fanotify_perm_event, SLAB_PANIC);
Miklos Szeredi6685df32017-10-30 21:14:56 +01001124 }
Eric Paris2a3edf82009-12-17 21:24:26 -05001125
1126 return 0;
1127}
1128device_initcall(fanotify_user_setup);