1 #include <linux/fanotify.h>
2 #include <linux/fdtable.h>
3 #include <linux/fsnotify_backend.h>
4 #include <linux/init.h>
5 #include <linux/jiffies.h>
6 #include <linux/kernel.h> /* UINT_MAX */
7 #include <linux/mount.h>
8 #include <linux/sched.h>
9 #include <linux/types.h>
10 #include <linux/wait.h>
12 static bool should_merge(struct fsnotify_event
*old
, struct fsnotify_event
*new)
14 pr_debug("%s: old=%p new=%p\n", __func__
, old
, new);
16 if (old
->to_tell
== new->to_tell
&&
17 old
->data_type
== new->data_type
&&
18 old
->tgid
== new->tgid
) {
19 switch (old
->data_type
) {
20 case (FSNOTIFY_EVENT_PATH
):
21 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
22 /* dont merge two permission events */
23 if ((old
->mask
& FAN_ALL_PERM_EVENTS
) &&
24 (new->mask
& FAN_ALL_PERM_EVENTS
))
27 if ((old
->path
.mnt
== new->path
.mnt
) &&
28 (old
->path
.dentry
== new->path
.dentry
))
31 case (FSNOTIFY_EVENT_NONE
):
40 /* and the list better be locked by something too! */
41 static struct fsnotify_event
*fanotify_merge(struct list_head
*list
,
42 struct fsnotify_event
*event
)
44 struct fsnotify_event_holder
*test_holder
;
45 struct fsnotify_event
*test_event
= NULL
;
46 struct fsnotify_event
*new_event
;
48 pr_debug("%s: list=%p event=%p\n", __func__
, list
, event
);
51 list_for_each_entry_reverse(test_holder
, list
, event_list
) {
52 if (should_merge(test_holder
->event
, event
)) {
53 test_event
= test_holder
->event
;
61 fsnotify_get_event(test_event
);
63 /* if they are exactly the same we are done */
64 if (test_event
->mask
== event
->mask
)
68 * if the refcnt == 2 this is the only queue
69 * for this event and so we can update the mask
72 if (atomic_read(&test_event
->refcnt
) == 2) {
73 test_event
->mask
|= event
->mask
;
77 new_event
= fsnotify_clone_event(test_event
);
79 /* done with test_event */
80 fsnotify_put_event(test_event
);
82 /* couldn't allocate memory, merge was not possible */
83 if (unlikely(!new_event
))
84 return ERR_PTR(-ENOMEM
);
86 /* build new event and replace it on the list */
87 new_event
->mask
= (test_event
->mask
| event
->mask
);
88 fsnotify_replace_event(test_holder
, new_event
);
90 /* we hold a reference on new_event from clone_event */
94 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
95 static int fanotify_get_response_from_access(struct fsnotify_group
*group
,
96 struct fsnotify_event
*event
)
100 pr_debug("%s: group=%p event=%p\n", __func__
, group
, event
);
102 wait_event(group
->fanotify_data
.access_waitq
, event
->response
||
103 atomic_read(&group
->fanotify_data
.bypass_perm
));
105 if (!event
->response
) /* bypass_perm set */
108 /* userspace responded, convert to something usable */
109 spin_lock(&event
->lock
);
110 switch (event
->response
) {
119 spin_unlock(&event
->lock
);
121 pr_debug("%s: group=%p event=%p about to return ret=%d\n", __func__
,
128 static int fanotify_handle_event(struct fsnotify_group
*group
,
129 struct fsnotify_mark
*inode_mark
,
130 struct fsnotify_mark
*fanotify_mark
,
131 struct fsnotify_event
*event
)
134 struct fsnotify_event
*notify_event
= NULL
;
136 BUILD_BUG_ON(FAN_ACCESS
!= FS_ACCESS
);
137 BUILD_BUG_ON(FAN_MODIFY
!= FS_MODIFY
);
138 BUILD_BUG_ON(FAN_CLOSE_NOWRITE
!= FS_CLOSE_NOWRITE
);
139 BUILD_BUG_ON(FAN_CLOSE_WRITE
!= FS_CLOSE_WRITE
);
140 BUILD_BUG_ON(FAN_OPEN
!= FS_OPEN
);
141 BUILD_BUG_ON(FAN_EVENT_ON_CHILD
!= FS_EVENT_ON_CHILD
);
142 BUILD_BUG_ON(FAN_Q_OVERFLOW
!= FS_Q_OVERFLOW
);
143 BUILD_BUG_ON(FAN_OPEN_PERM
!= FS_OPEN_PERM
);
144 BUILD_BUG_ON(FAN_ACCESS_PERM
!= FS_ACCESS_PERM
);
145 BUILD_BUG_ON(FAN_ONDIR
!= FS_ISDIR
);
147 pr_debug("%s: group=%p event=%p\n", __func__
, group
, event
);
149 notify_event
= fsnotify_add_notify_event(group
, event
, NULL
, fanotify_merge
);
150 if (IS_ERR(notify_event
))
151 return PTR_ERR(notify_event
);
153 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
154 if (event
->mask
& FAN_ALL_PERM_EVENTS
) {
155 /* if we merged we need to wait on the new event */
157 event
= notify_event
;
158 ret
= fanotify_get_response_from_access(group
, event
);
163 fsnotify_put_event(notify_event
);
168 static bool fanotify_should_send_event(struct fsnotify_group
*group
,
169 struct inode
*to_tell
,
170 struct fsnotify_mark
*inode_mark
,
171 struct fsnotify_mark
*vfsmnt_mark
,
172 __u32 event_mask
, void *data
, int data_type
)
174 __u32 marks_mask
, marks_ignored_mask
;
175 struct path
*path
= data
;
177 pr_debug("%s: group=%p to_tell=%p inode_mark=%p vfsmnt_mark=%p "
178 "mask=%x data=%p data_type=%d\n", __func__
, group
, to_tell
,
179 inode_mark
, vfsmnt_mark
, event_mask
, data
, data_type
);
181 /* if we don't have enough info to send an event to userspace say no */
182 if (data_type
!= FSNOTIFY_EVENT_PATH
)
185 /* sorry, fanotify only gives a damn about files and dirs */
186 if (!S_ISREG(path
->dentry
->d_inode
->i_mode
) &&
187 !S_ISDIR(path
->dentry
->d_inode
->i_mode
))
190 if (inode_mark
&& vfsmnt_mark
) {
191 marks_mask
= (vfsmnt_mark
->mask
| inode_mark
->mask
);
192 marks_ignored_mask
= (vfsmnt_mark
->ignored_mask
| inode_mark
->ignored_mask
);
193 } else if (inode_mark
) {
195 * if the event is for a child and this inode doesn't care about
196 * events on the child, don't send it!
198 if ((event_mask
& FS_EVENT_ON_CHILD
) &&
199 !(inode_mark
->mask
& FS_EVENT_ON_CHILD
))
201 marks_mask
= inode_mark
->mask
;
202 marks_ignored_mask
= inode_mark
->ignored_mask
;
203 } else if (vfsmnt_mark
) {
204 marks_mask
= vfsmnt_mark
->mask
;
205 marks_ignored_mask
= vfsmnt_mark
->ignored_mask
;
210 if (S_ISDIR(path
->dentry
->d_inode
->i_mode
) &&
211 (marks_ignored_mask
& FS_ISDIR
))
214 if (event_mask
& marks_mask
& ~marks_ignored_mask
)
220 static void fanotify_free_group_priv(struct fsnotify_group
*group
)
222 struct user_struct
*user
;
224 user
= group
->fanotify_data
.user
;
225 atomic_dec(&user
->fanotify_listeners
);
229 const struct fsnotify_ops fanotify_fsnotify_ops
= {
230 .handle_event
= fanotify_handle_event
,
231 .should_send_event
= fanotify_should_send_event
,
232 .free_group_priv
= fanotify_free_group_priv
,
233 .free_event_priv
= NULL
,
234 .freeing_mark
= NULL
,