diff options
author | Eric Paris <eparis@redhat.com> | 2009-08-16 21:51:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-08-17 16:37:37 -0400 |
commit | eef3a116be11d35396efb2a8cc7345fd3221e294 (patch) | |
tree | 2a5d0b36dd5985f29eac43f51b03e610e40b7c9b /fs/notify/inotify | |
parent | 0f66f96d21b4bbff49baaa337546e687d7c58e87 (diff) |
notify: unused event private race
inotify decides if private data it passed to get added to an event was
used by checking list_empty(). But it's possible that the event may
have been dequeued and the private event removed so it would look empty.
The fix is to use the return code from fsnotify_add_notify_event rather
than looking at the list.
Signed-off-by: Eric Paris <eparis@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/notify/inotify')
-rw-r--r-- | fs/notify/inotify/inotify_fsnotify.c | 13 | ||||
-rw-r--r-- | fs/notify/inotify/inotify_user.c | 7 |
2 files changed, 10 insertions, 10 deletions
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index 47cd258fd24d..5dcbafe72d71 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c | |||
@@ -62,13 +62,14 @@ static int inotify_handle_event(struct fsnotify_group *group, struct fsnotify_ev | |||
62 | event_priv->wd = wd; | 62 | event_priv->wd = wd; |
63 | 63 | ||
64 | ret = fsnotify_add_notify_event(group, event, fsn_event_priv); | 64 | ret = fsnotify_add_notify_event(group, event, fsn_event_priv); |
65 | /* EEXIST is not an error */ | 65 | if (ret) { |
66 | if (ret == -EEXIST) | ||
67 | ret = 0; | ||
68 | |||
69 | /* did event_priv get attached? */ | ||
70 | if (list_empty(&fsn_event_priv->event_list)) | ||
71 | inotify_free_event_priv(fsn_event_priv); | 66 | inotify_free_event_priv(fsn_event_priv); |
67 | /* EEXIST says we tail matched, EOVERFLOW isn't something | ||
68 | * to report up the stack. */ | ||
69 | if ((ret == -EEXIST) || | ||
70 | (ret == -EOVERFLOW)) | ||
71 | ret = 0; | ||
72 | } | ||
72 | 73 | ||
73 | /* | 74 | /* |
74 | * If we hold the entry until after the event is on the queue | 75 | * If we hold the entry until after the event is on the queue |
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index f30d9bbc2e1b..c172a7a17b17 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
@@ -386,6 +386,7 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark_entry *entry, | |||
386 | struct fsnotify_event *ignored_event; | 386 | struct fsnotify_event *ignored_event; |
387 | struct inotify_event_private_data *event_priv; | 387 | struct inotify_event_private_data *event_priv; |
388 | struct fsnotify_event_private_data *fsn_event_priv; | 388 | struct fsnotify_event_private_data *fsn_event_priv; |
389 | int ret; | ||
389 | 390 | ||
390 | ignored_event = fsnotify_create_event(NULL, FS_IN_IGNORED, NULL, | 391 | ignored_event = fsnotify_create_event(NULL, FS_IN_IGNORED, NULL, |
391 | FSNOTIFY_EVENT_NONE, NULL, 0, | 392 | FSNOTIFY_EVENT_NONE, NULL, 0, |
@@ -404,10 +405,8 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark_entry *entry, | |||
404 | fsn_event_priv->group = group; | 405 | fsn_event_priv->group = group; |
405 | event_priv->wd = ientry->wd; | 406 | event_priv->wd = ientry->wd; |
406 | 407 | ||
407 | fsnotify_add_notify_event(group, ignored_event, fsn_event_priv); | 408 | ret = fsnotify_add_notify_event(group, ignored_event, fsn_event_priv); |
408 | 409 | if (ret) | |
409 | /* did the private data get added? */ | ||
410 | if (list_empty(&fsn_event_priv->event_list)) | ||
411 | inotify_free_event_priv(fsn_event_priv); | 410 | inotify_free_event_priv(fsn_event_priv); |
412 | 411 | ||
413 | skip_send_ignore: | 412 | skip_send_ignore: |