diff options
author | Eric Paris <eparis@redhat.com> | 2010-10-28 17:21:58 -0400 |
---|---|---|
committer | Eric Paris <eparis@redhat.com> | 2010-10-28 17:22:15 -0400 |
commit | 4afeff8505cb8a38e36c1ef2bd3447c4b8f87367 (patch) | |
tree | 50a80d8773698813e4e9d9f9112079c09d493c48 /fs | |
parent | ac7e22dcfafd04c842a02057afd6541c1d613ef9 (diff) |
fanotify: limit number of listeners per user
fanotify currently has no limit on the number of listeners a given user can
have open. This patch limits the total number of listeners per user to
128. This is the same as the inotify default limit.
Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/notify/fanotify/fanotify.c | 11 | ||||
-rw-r--r-- | fs/notify/fanotify/fanotify_user.c | 11 |
2 files changed, 21 insertions, 1 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 85366c78cc37..60c11c306fd9 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
@@ -200,10 +200,19 @@ static bool fanotify_should_send_event(struct fsnotify_group *group, | |||
200 | return false; | 200 | return false; |
201 | } | 201 | } |
202 | 202 | ||
203 | static void fanotify_free_group_priv(struct fsnotify_group *group) | ||
204 | { | ||
205 | struct user_struct *user; | ||
206 | |||
207 | user = group->fanotify_data.user; | ||
208 | atomic_dec(&user->fanotify_listeners); | ||
209 | free_uid(user); | ||
210 | } | ||
211 | |||
203 | const struct fsnotify_ops fanotify_fsnotify_ops = { | 212 | const struct fsnotify_ops fanotify_fsnotify_ops = { |
204 | .handle_event = fanotify_handle_event, | 213 | .handle_event = fanotify_handle_event, |
205 | .should_send_event = fanotify_should_send_event, | 214 | .should_send_event = fanotify_should_send_event, |
206 | .free_group_priv = NULL, | 215 | .free_group_priv = fanotify_free_group_priv, |
207 | .free_event_priv = NULL, | 216 | .free_event_priv = NULL, |
208 | .freeing_mark = NULL, | 217 | .freeing_mark = NULL, |
209 | }; | 218 | }; |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index f9216102b426..a7d9369482d5 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #define FANOTIFY_DEFAULT_MAX_EVENTS 16384 | 19 | #define FANOTIFY_DEFAULT_MAX_EVENTS 16384 |
20 | #define FANOTIFY_DEFAULT_MAX_MARKS 8192 | 20 | #define FANOTIFY_DEFAULT_MAX_MARKS 8192 |
21 | #define FANOTIFY_DEFAULT_MAX_LISTENERS 128 | ||
21 | 22 | ||
22 | extern const struct fsnotify_ops fanotify_fsnotify_ops; | 23 | extern const struct fsnotify_ops fanotify_fsnotify_ops; |
23 | 24 | ||
@@ -656,6 +657,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
656 | { | 657 | { |
657 | struct fsnotify_group *group; | 658 | struct fsnotify_group *group; |
658 | int f_flags, fd; | 659 | int f_flags, fd; |
660 | struct user_struct *user; | ||
659 | 661 | ||
660 | pr_debug("%s: flags=%d event_f_flags=%d\n", | 662 | pr_debug("%s: flags=%d event_f_flags=%d\n", |
661 | __func__, flags, event_f_flags); | 663 | __func__, flags, event_f_flags); |
@@ -666,6 +668,12 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
666 | if (flags & ~FAN_ALL_INIT_FLAGS) | 668 | if (flags & ~FAN_ALL_INIT_FLAGS) |
667 | return -EINVAL; | 669 | return -EINVAL; |
668 | 670 | ||
671 | user = get_current_user(); | ||
672 | if (atomic_read(&user->fanotify_listeners) > FANOTIFY_DEFAULT_MAX_LISTENERS) { | ||
673 | free_uid(user); | ||
674 | return -EMFILE; | ||
675 | } | ||
676 | |||
669 | f_flags = O_RDWR | FMODE_NONOTIFY; | 677 | f_flags = O_RDWR | FMODE_NONOTIFY; |
670 | if (flags & FAN_CLOEXEC) | 678 | if (flags & FAN_CLOEXEC) |
671 | f_flags |= O_CLOEXEC; | 679 | f_flags |= O_CLOEXEC; |
@@ -677,6 +685,9 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
677 | if (IS_ERR(group)) | 685 | if (IS_ERR(group)) |
678 | return PTR_ERR(group); | 686 | return PTR_ERR(group); |
679 | 687 | ||
688 | group->fanotify_data.user = user; | ||
689 | atomic_inc(&user->fanotify_listeners); | ||
690 | |||
680 | group->fanotify_data.f_flags = event_f_flags; | 691 | group->fanotify_data.f_flags = event_f_flags; |
681 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | 692 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS |
682 | mutex_init(&group->fanotify_data.access_mutex); | 693 | mutex_init(&group->fanotify_data.access_mutex); |