diff options
| -rw-r--r-- | fs/notify/inotify/inotify_fsnotify.c | 1 | ||||
| -rw-r--r-- | fs/notify/inotify/inotify_user.c | 39 |
2 files changed, 14 insertions, 26 deletions
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index a91b69a6a291..0348d0c8f65e 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c | |||
| @@ -198,6 +198,7 @@ static void inotify_free_group_priv(struct fsnotify_group *group) | |||
| 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 | ||
