Commit | Line | Data |
---|---|---|
11637e4b EP |
1 | #include <linux/fcntl.h> |
2 | #include <linux/fs.h> | |
52c923dd | 3 | #include <linux/anon_inodes.h> |
11637e4b EP |
4 | #include <linux/fsnotify_backend.h> |
5 | #include <linux/security.h> | |
6 | #include <linux/syscalls.h> | |
7 | ||
8 | #include "fanotify.h" | |
9 | ||
52c923dd EP |
10 | static int fanotify_release(struct inode *ignored, struct file *file) |
11 | { | |
12 | struct fsnotify_group *group = file->private_data; | |
13 | ||
14 | pr_debug("%s: file=%p group=%p\n", __func__, file, group); | |
15 | ||
16 | /* matches the fanotify_init->fsnotify_alloc_group */ | |
17 | fsnotify_put_group(group); | |
18 | ||
19 | return 0; | |
20 | } | |
21 | ||
22 | static const struct file_operations fanotify_fops = { | |
23 | .poll = NULL, | |
24 | .read = NULL, | |
25 | .fasync = NULL, | |
26 | .release = fanotify_release, | |
27 | .unlocked_ioctl = NULL, | |
28 | .compat_ioctl = NULL, | |
29 | }; | |
30 | ||
31 | /* fanotify syscalls */ | |
11637e4b EP |
32 | SYSCALL_DEFINE3(fanotify_init, unsigned int, flags, unsigned int, event_f_flags, |
33 | unsigned int, priority) | |
34 | { | |
52c923dd EP |
35 | struct fsnotify_group *group; |
36 | int f_flags, fd; | |
37 | ||
38 | pr_debug("%s: flags=%d event_f_flags=%d priority=%d\n", | |
39 | __func__, flags, event_f_flags, priority); | |
40 | ||
41 | if (event_f_flags) | |
42 | return -EINVAL; | |
43 | if (priority) | |
44 | return -EINVAL; | |
45 | ||
46 | if (!capable(CAP_SYS_ADMIN)) | |
47 | return -EACCES; | |
48 | ||
49 | if (flags & ~FAN_ALL_INIT_FLAGS) | |
50 | return -EINVAL; | |
51 | ||
52 | f_flags = (O_RDONLY | FMODE_NONOTIFY); | |
53 | if (flags & FAN_CLOEXEC) | |
54 | f_flags |= O_CLOEXEC; | |
55 | if (flags & FAN_NONBLOCK) | |
56 | f_flags |= O_NONBLOCK; | |
57 | ||
58 | /* fsnotify_alloc_group takes a ref. Dropped in fanotify_release */ | |
59 | group = fsnotify_alloc_group(&fanotify_fsnotify_ops); | |
60 | if (IS_ERR(group)) | |
61 | return PTR_ERR(group); | |
62 | ||
63 | fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags); | |
64 | if (fd < 0) | |
65 | goto out_put_group; | |
66 | ||
67 | return fd; | |
68 | ||
69 | out_put_group: | |
70 | fsnotify_put_group(group); | |
71 | return fd; | |
11637e4b | 72 | } |
bbaa4168 EP |
73 | |
74 | SYSCALL_DEFINE5(fanotify_mark, int, fanotify_fd, unsigned int, flags, | |
75 | __u64, mask, int, dfd, const char __user *, pathname) | |
76 | { | |
77 | return -ENOSYS; | |
78 | } |