diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index c18459cea6f4..85eda539b35f 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -70,7 +70,7 @@ static bool fanotify_name_event_equal(struct fanotify_name_event *fne1, return !memcmp(fne1->name, fne2->name, fne1->name_len); } -static bool should_merge(struct fsnotify_event *old_fsn, +static bool fanotify_should_merge(struct fsnotify_event *old_fsn, struct fsnotify_event *new_fsn) { struct fanotify_event *old, *new; @@ -129,7 +129,7 @@ static int fanotify_merge(struct list_head *list, struct fsnotify_event *event) return 0; list_for_each_entry_reverse(test_event, list, list) { - if (should_merge(test_event, event)) { + if (fanotify_should_merge(test_event, event)) { FANOTIFY_E(test_event)->mask |= new->mask; return 1; } @@ -232,6 +232,10 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, if (!fsnotify_iter_should_report_type(iter_info, type)) continue; mark = iter_info->marks[type]; + + /* Apply ignore mask regardless of ISDIR and ON_CHILD flags */ + marks_ignored_mask |= mark->ignored_mask; + /* * If the event is on dir and this mark doesn't care about * events on dir, don't send it! @@ -249,7 +253,6 @@ static u32 fanotify_group_event_mask(struct fsnotify_group *group, continue; marks_mask |= mark->mask; - marks_ignored_mask |= mark->ignored_mask; } test_mask = event_mask & marks_mask & ~marks_ignored_mask; diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index 35bfbf4a7aac..8ce7ccfc4b0d 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -89,7 +89,7 @@ struct fanotify_name_event { __kernel_fsid_t fsid; struct fanotify_fh dir_fh; u8 name_len; - char name[0]; + char name[]; }; static inline struct fanotify_name_event * diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 42cb794c62ac..63b5dffdca9e 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -328,7 +328,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, ret = -EFAULT; /* * Sanity check copy size in case get_one_event() and - * fill_event_metadata() event_len sizes ever get out of sync. + * event_len sizes ever get out of sync. */ if (WARN_ON_ONCE(metadata.event_len > count)) goto out_close_fd; @@ -487,8 +487,10 @@ static ssize_t fanotify_write(struct file *file, const char __user *buf, size_t group = file->private_data; - if (count > sizeof(response)) - count = sizeof(response); + if (count < sizeof(response)) + return -EINVAL; + + count = sizeof(response); pr_debug("%s: group=%p count=%zu\n", __func__, group, count); diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c index ef83f4020554..f0d6b54be412 100644 --- a/fs/notify/fdinfo.c +++ b/fs/notify/fdinfo.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include "inotify/inotify.h" diff --git a/fs/notify/group.c b/fs/notify/group.c index 133f723aca07..a4a4b1c64d32 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c @@ -25,6 +25,7 @@ static void fsnotify_final_destroy_group(struct fsnotify_group *group) group->ops->free_group_priv(group); mem_cgroup_put(group->memcg); + mutex_destroy(&group->mark_mutex); kfree(group); } diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 81ffc8629fc4..f88bbcc9efeb 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -764,20 +764,18 @@ SYSCALL_DEFINE2(inotify_rm_watch, int, fd, __s32, wd) struct fsnotify_group *group; struct inotify_inode_mark *i_mark; struct fd f; - int ret = 0; + int ret = -EINVAL; f = fdget(fd); if (unlikely(!f.file)) return -EBADF; /* verify that this is indeed an inotify instance */ - ret = -EINVAL; if (unlikely(f.file->f_op != &inotify_fops)) goto out; group = f.file->private_data; - ret = -EINVAL; i_mark = inotify_idr_find(group, wd); if (unlikely(!i_mark)) goto out; diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 1d96216dffd1..8387937b9d01 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -325,13 +325,16 @@ static void fsnotify_put_mark_wake(struct fsnotify_mark *mark) } bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info) + __releases(&fsnotify_mark_srcu) { int type; fsnotify_foreach_obj_type(type) { /* This can fail if mark is being removed */ - if (!fsnotify_get_mark_safe(iter_info->marks[type])) + if (!fsnotify_get_mark_safe(iter_info->marks[type])) { + __release(&fsnotify_mark_srcu); goto fail; + } } /* @@ -350,6 +353,7 @@ bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info) } void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info) + __acquires(&fsnotify_mark_srcu) { int type;