diff options
Diffstat (limited to 'fs/notify')
-rw-r--r-- | fs/notify/fanotify/fanotify_user.c | 2 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_fsnotify.c | 3 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_user.c | 39 | ||||
-rw-r--r-- | fs/notify/mark.c | 2 |
4 files changed, 17 insertions, 29 deletions
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 6b1305dc26c0..9fde1c00a296 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -164,7 +164,7 @@ static int process_access_response(struct fsnotify_group *group, | |||
164 | fd, response); | 164 | fd, response); |
165 | /* | 165 | /* |
166 | * make sure the response is valid, if invalid we do nothing and either | 166 | * make sure the response is valid, if invalid we do nothing and either |
167 | * userspace can send a valid responce or we will clean it up after the | 167 | * userspace can send a valid response or we will clean it up after the |
168 | * timeout | 168 | * timeout |
169 | */ | 169 | */ |
170 | switch (response) { | 170 | switch (response) { |
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index a91b69a6a291..e3cbd746f64a 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c | |||
@@ -194,10 +194,11 @@ static int idr_callback(int id, void *p, void *data) | |||
194 | 194 | ||
195 | static void inotify_free_group_priv(struct fsnotify_group *group) | 195 | static void inotify_free_group_priv(struct fsnotify_group *group) |
196 | { | 196 | { |
197 | /* ideally the idr is empty and we won't hit the BUG in teh callback */ | 197 | /* ideally the idr is empty and we won't hit the BUG in the callback */ |
198 | idr_for_each(&group->inotify_data.idr, idr_callback, group); | 198 | idr_for_each(&group->inotify_data.idr, idr_callback, group); |
199 | idr_remove_all(&group->inotify_data.idr); | 199 | idr_remove_all(&group->inotify_data.idr); |
200 | idr_destroy(&group->inotify_data.idr); | 200 | idr_destroy(&group->inotify_data.idr); |
201 | atomic_dec(&group->inotify_data.user->inotify_devs); | ||
201 | free_uid(group->inotify_data.user); | 202 | free_uid(group->inotify_data.user); |
202 | } | 203 | } |
203 | 204 | ||
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index bd46e7c8a0ef..8445fbc8985c 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
@@ -290,7 +290,6 @@ static int inotify_fasync(int fd, struct file *file, int on) | |||
290 | static int inotify_release(struct inode *ignored, struct file *file) | 290 | static int inotify_release(struct inode *ignored, struct file *file) |
291 | { | 291 | { |
292 | struct fsnotify_group *group = file->private_data; | 292 | struct fsnotify_group *group = file->private_data; |
293 | struct user_struct *user = group->inotify_data.user; | ||
294 | 293 | ||
295 | pr_debug("%s: group=%p\n", __func__, group); | 294 | pr_debug("%s: group=%p\n", __func__, group); |
296 | 295 | ||
@@ -299,8 +298,6 @@ static int inotify_release(struct inode *ignored, struct file *file) | |||
299 | /* free this group, matching get was inotify_init->fsnotify_obtain_group */ | 298 | /* free this group, matching get was inotify_init->fsnotify_obtain_group */ |
300 | fsnotify_put_group(group); | 299 | fsnotify_put_group(group); |
301 | 300 | ||
302 | atomic_dec(&user->inotify_devs); | ||
303 | |||
304 | return 0; | 301 | return 0; |
305 | } | 302 | } |
306 | 303 | ||
@@ -697,7 +694,7 @@ retry: | |||
697 | return ret; | 694 | return ret; |
698 | } | 695 | } |
699 | 696 | ||
700 | static struct fsnotify_group *inotify_new_group(struct user_struct *user, unsigned int max_events) | 697 | static struct fsnotify_group *inotify_new_group(unsigned int max_events) |
701 | { | 698 | { |
702 | struct fsnotify_group *group; | 699 | struct fsnotify_group *group; |
703 | 700 | ||
@@ -710,8 +707,14 @@ static struct fsnotify_group *inotify_new_group(struct user_struct *user, unsign | |||
710 | spin_lock_init(&group->inotify_data.idr_lock); | 707 | spin_lock_init(&group->inotify_data.idr_lock); |
711 | idr_init(&group->inotify_data.idr); | 708 | idr_init(&group->inotify_data.idr); |
712 | group->inotify_data.last_wd = 0; | 709 | group->inotify_data.last_wd = 0; |
713 | group->inotify_data.user = user; | ||
714 | group->inotify_data.fa = NULL; | 710 | group->inotify_data.fa = NULL; |
711 | group->inotify_data.user = get_current_user(); | ||
712 | |||
713 | if (atomic_inc_return(&group->inotify_data.user->inotify_devs) > | ||
714 | inotify_max_user_instances) { | ||
715 | fsnotify_put_group(group); | ||
716 | return ERR_PTR(-EMFILE); | ||
717 | } | ||
715 | 718 | ||
716 | return group; | 719 | return group; |
717 | } | 720 | } |
@@ -721,7 +724,6 @@ static struct fsnotify_group *inotify_new_group(struct user_struct *user, unsign | |||
721 | SYSCALL_DEFINE1(inotify_init1, int, flags) | 724 | SYSCALL_DEFINE1(inotify_init1, int, flags) |
722 | { | 725 | { |
723 | struct fsnotify_group *group; | 726 | struct fsnotify_group *group; |
724 | struct user_struct *user; | ||
725 | int ret; | 727 | int ret; |
726 | 728 | ||
727 | /* Check the IN_* constants for consistency. */ | 729 | /* Check the IN_* constants for consistency. */ |
@@ -731,31 +733,16 @@ SYSCALL_DEFINE1(inotify_init1, int, flags) | |||
731 | if (flags & ~(IN_CLOEXEC | IN_NONBLOCK)) | 733 | if (flags & ~(IN_CLOEXEC | IN_NONBLOCK)) |
732 | return -EINVAL; | 734 | return -EINVAL; |
733 | 735 | ||
734 | user = get_current_user(); | ||
735 | if (unlikely(atomic_read(&user->inotify_devs) >= | ||
736 | inotify_max_user_instances)) { | ||
737 | ret = -EMFILE; | ||
738 | goto out_free_uid; | ||
739 | } | ||
740 | |||
741 | /* fsnotify_obtain_group took a reference to group, we put this when we kill the file in the end */ | 736 | /* fsnotify_obtain_group took a reference to group, we put this when we kill the file in the end */ |
742 | group = inotify_new_group(user, inotify_max_queued_events); | 737 | group = inotify_new_group(inotify_max_queued_events); |
743 | if (IS_ERR(group)) { | 738 | if (IS_ERR(group)) |
744 | ret = PTR_ERR(group); | 739 | return PTR_ERR(group); |
745 | goto out_free_uid; | ||
746 | } | ||
747 | |||
748 | atomic_inc(&user->inotify_devs); | ||
749 | 740 | ||
750 | ret = anon_inode_getfd("inotify", &inotify_fops, group, | 741 | ret = anon_inode_getfd("inotify", &inotify_fops, group, |
751 | O_RDONLY | flags); | 742 | O_RDONLY | flags); |
752 | if (ret >= 0) | 743 | if (ret < 0) |
753 | return ret; | 744 | fsnotify_put_group(group); |
754 | 745 | ||
755 | fsnotify_put_group(group); | ||
756 | atomic_dec(&user->inotify_devs); | ||
757 | out_free_uid: | ||
758 | free_uid(user); | ||
759 | return ret; | 746 | return ret; |
760 | } | 747 | } |
761 | 748 | ||
diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 50c00856f730..252ab1f6452b 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c | |||
@@ -24,7 +24,7 @@ | |||
24 | * referencing this object. The object typically will live inside the kernel | 24 | * referencing this object. The object typically will live inside the kernel |
25 | * with a refcnt of 2, one for each list it is on (i_list, g_list). Any task | 25 | * with a refcnt of 2, one for each list it is on (i_list, g_list). Any task |
26 | * which can find this object holding the appropriete locks, can take a reference | 26 | * which can find this object holding the appropriete locks, can take a reference |
27 | * and the object itself is guarenteed to survive until the reference is dropped. | 27 | * and the object itself is guaranteed to survive until the reference is dropped. |
28 | * | 28 | * |
29 | * LOCKING: | 29 | * LOCKING: |
30 | * There are 3 spinlocks involved with fsnotify inode marks and they MUST | 30 | * There are 3 spinlocks involved with fsnotify inode marks and they MUST |