aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify/fanotify/fanotify.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2014-01-28 15:38:06 -0500
committerJan Kara <jack@suse.cz>2014-01-29 07:57:17 -0500
commit85816794240b9659e66e4d9b0df7c6e814e5f603 (patch)
treedd9a5103e62f15e74b2d7729e972d141845462aa /fs/notify/fanotify/fanotify.c
parent83c0e1b442b488571f4fef4a91c2fe52eed6c705 (diff)
fanotify: Fix use after free for permission events
Currently struct fanotify_event_info has been destroyed immediately after reporting its contents to userspace. However that is wrong for permission events because those need to stay around until userspace provides response which is filled back in fanotify_event_info. So change to code to free permission events only after we have got the response from userspace. Reported-and-tested-by: Jiri Kosina <jkosina@suse.cz> Reported-and-tested-by: Dave Jones <davej@fedoraproject.org> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/notify/fanotify/fanotify.c')
-rw-r--r--fs/notify/fanotify/fanotify.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index c7e5e8f54748..0e792f5e3147 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -192,14 +192,17 @@ static int fanotify_handle_event(struct fsnotify_group *group,
192 192
193 ret = fsnotify_add_notify_event(group, fsn_event, fanotify_merge); 193 ret = fsnotify_add_notify_event(group, fsn_event, fanotify_merge);
194 if (ret) { 194 if (ret) {
195 BUG_ON(mask & FAN_ALL_PERM_EVENTS);
195 /* Our event wasn't used in the end. Free it. */ 196 /* Our event wasn't used in the end. Free it. */
196 fsnotify_destroy_event(group, fsn_event); 197 fsnotify_destroy_event(group, fsn_event);
197 ret = 0; 198 ret = 0;
198 } 199 }
199 200
200#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS 201#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
201 if (mask & FAN_ALL_PERM_EVENTS) 202 if (mask & FAN_ALL_PERM_EVENTS) {
202 ret = fanotify_get_response_from_access(group, event); 203 ret = fanotify_get_response_from_access(group, event);
204 fsnotify_destroy_event(group, fsn_event);
205 }
203#endif 206#endif
204 return ret; 207 return ret;
205} 208}