summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-11-08 18:08:14 -0500
committerEric Paris <eparis@redhat.com>2010-12-07 16:14:17 -0500
commitecf6f5e7d68471b08603f7c20143ac236602364f (patch)
treefb6fc404022d4674c2cb8e9a31f98a719a316e14
parente8a7e48bb248a1196484d3f8afa53bded2b24e71 (diff)
fanotify: deny permissions when no event was sent
If no event was sent to userspace we cannot expect userspace to respond to permissions requests. Today such requests just hang forever. This patch will deny any permissions event which was unable to be sent to userspace. Reported-by: Tvrtko Ursulin <tvrtko.ursulin@sophos.com> Signed-off-by: Eric Paris <eparis@redhat.com>
-rw-r--r--fs/notify/fanotify/fanotify_user.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index 063224812b7e..045c0794d435 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -106,7 +106,7 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event)
return client_fd;
}
-static ssize_t fill_event_metadata(struct fsnotify_group *group,
+static int fill_event_metadata(struct fsnotify_group *group,
struct fanotify_event_metadata *metadata,
struct fsnotify_event *event)
{
@@ -257,10 +257,11 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
pr_debug("%s: group=%p event=%p\n", __func__, group, event);
- fd = fill_event_metadata(group, &fanotify_event_metadata, event);
- if (fd < 0)
- return fd;
+ ret = fill_event_metadata(group, &fanotify_event_metadata, event);
+ if (ret < 0)
+ goto out;
+ fd = ret;
ret = prepare_for_access_response(group, event, fd);
if (ret)
goto out_close_fd;
@@ -275,6 +276,13 @@ out_kill_access_response:
remove_access_response(group, event, fd);
out_close_fd:
sys_close(fd);
+out:
+#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
+ if (event->mask & FAN_ALL_PERM_EVENTS) {
+ event->response = FAN_DENY;
+ wake_up(&group->fanotify_data.access_waitq);
+ }
+#endif
return ret;
}