diff options
-rw-r--r-- | fs/notify/fanotify/fanotify.c | 19 | ||||
-rw-r--r-- | fs/notify/fanotify/fanotify.h | 3 | ||||
-rw-r--r-- | fs/notify/fanotify/fanotify_user.c | 2 |
3 files changed, 17 insertions, 7 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 6702a6a0bbb5..928f2a5eedb7 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
@@ -139,23 +139,32 @@ static bool fanotify_should_send_event(struct fsnotify_mark *inode_mark, | |||
139 | return false; | 139 | return false; |
140 | } | 140 | } |
141 | 141 | ||
142 | struct fanotify_event_info *fanotify_alloc_event(struct inode *inode, u32 mask, | 142 | struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group, |
143 | struct inode *inode, u32 mask, | ||
143 | const struct path *path) | 144 | const struct path *path) |
144 | { | 145 | { |
145 | struct fanotify_event_info *event; | 146 | struct fanotify_event_info *event; |
147 | gfp_t gfp = GFP_KERNEL; | ||
148 | |||
149 | /* | ||
150 | * For queues with unlimited length lost events are not expected and | ||
151 | * can possibly have security implications. Avoid losing events when | ||
152 | * memory is short. | ||
153 | */ | ||
154 | if (group->max_events == UINT_MAX) | ||
155 | gfp |= __GFP_NOFAIL; | ||
146 | 156 | ||
147 | if (fanotify_is_perm_event(mask)) { | 157 | if (fanotify_is_perm_event(mask)) { |
148 | struct fanotify_perm_event_info *pevent; | 158 | struct fanotify_perm_event_info *pevent; |
149 | 159 | ||
150 | pevent = kmem_cache_alloc(fanotify_perm_event_cachep, | 160 | pevent = kmem_cache_alloc(fanotify_perm_event_cachep, gfp); |
151 | GFP_KERNEL); | ||
152 | if (!pevent) | 161 | if (!pevent) |
153 | return NULL; | 162 | return NULL; |
154 | event = &pevent->fae; | 163 | event = &pevent->fae; |
155 | pevent->response = 0; | 164 | pevent->response = 0; |
156 | goto init; | 165 | goto init; |
157 | } | 166 | } |
158 | event = kmem_cache_alloc(fanotify_event_cachep, GFP_KERNEL); | 167 | event = kmem_cache_alloc(fanotify_event_cachep, gfp); |
159 | if (!event) | 168 | if (!event) |
160 | return NULL; | 169 | return NULL; |
161 | init: __maybe_unused | 170 | init: __maybe_unused |
@@ -210,7 +219,7 @@ static int fanotify_handle_event(struct fsnotify_group *group, | |||
210 | return 0; | 219 | return 0; |
211 | } | 220 | } |
212 | 221 | ||
213 | event = fanotify_alloc_event(inode, mask, data); | 222 | event = fanotify_alloc_event(group, inode, mask, data); |
214 | ret = -ENOMEM; | 223 | ret = -ENOMEM; |
215 | if (unlikely(!event)) | 224 | if (unlikely(!event)) |
216 | goto finish; | 225 | goto finish; |
diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index 256d9d1ddea9..8609ba06f474 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h | |||
@@ -52,5 +52,6 @@ static inline struct fanotify_event_info *FANOTIFY_E(struct fsnotify_event *fse) | |||
52 | return container_of(fse, struct fanotify_event_info, fse); | 52 | return container_of(fse, struct fanotify_event_info, fse); |
53 | } | 53 | } |
54 | 54 | ||
55 | struct fanotify_event_info *fanotify_alloc_event(struct inode *inode, u32 mask, | 55 | struct fanotify_event_info *fanotify_alloc_event(struct fsnotify_group *group, |
56 | struct inode *inode, u32 mask, | ||
56 | const struct path *path); | 57 | const struct path *path); |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index c07eb3d655ea..72e367822efb 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -757,7 +757,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
757 | group->fanotify_data.user = user; | 757 | group->fanotify_data.user = user; |
758 | atomic_inc(&user->fanotify_listeners); | 758 | atomic_inc(&user->fanotify_listeners); |
759 | 759 | ||
760 | oevent = fanotify_alloc_event(NULL, FS_Q_OVERFLOW, NULL); | 760 | oevent = fanotify_alloc_event(group, NULL, FS_Q_OVERFLOW, NULL); |
761 | if (unlikely(!oevent)) { | 761 | if (unlikely(!oevent)) { |
762 | fd = -ENOMEM; | 762 | fd = -ENOMEM; |
763 | goto out_destroy_group; | 763 | goto out_destroy_group; |