Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 75fe2b2

Browse files
committed
inotify: do not leak inode marks in inotify_add_watch
inotify_add_watch had a couple of problems. The biggest being that if inotify_add_watch was called on the same inode twice (to update or change the event mask) a refence was taken on the original inode mark by fsnotify_find_mark_entry but was not being dropped at the end of the inotify_add_watch call. Thus if inotify_rm_watch was called although the mark was removed from the inode, the refcnt wouldn't hit zero and we would leak memory. Reported-by: Catalin Marinas <[email protected]> Signed-off-by: Eric Paris <[email protected]>
1 parent 5549f7c commit 75fe2b2

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

fs/notify/inotify/inotify_user.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -463,9 +463,6 @@ static int inotify_update_watch(struct fsnotify_group *group, struct inode *inod
463463
goto out_err;
464464

465465
spin_lock(&group->inotify_data.idr_lock);
466-
/* if entry is added to the idr we keep the reference obtained
467-
* through fsnotify_mark_add. remember to drop this reference
468-
* when entry is removed from idr */
469466
ret = idr_get_new_above(&group->inotify_data.idr, entry,
470467
++group->inotify_data.last_wd,
471468
&ientry->wd);
@@ -476,8 +473,13 @@ static int inotify_update_watch(struct fsnotify_group *group, struct inode *inod
476473
goto out_err;
477474
}
478475
atomic_inc(&group->inotify_data.user->inotify_watches);
476+
477+
/* we put the mark on the idr, take a reference */
478+
fsnotify_get_mark(entry);
479479
}
480480

481+
ret = ientry->wd;
482+
481483
spin_lock(&entry->lock);
482484

483485
old_mask = entry->mask;
@@ -508,7 +510,11 @@ static int inotify_update_watch(struct fsnotify_group *group, struct inode *inod
508510
fsnotify_recalc_group_mask(group);
509511
}
510512

511-
return ientry->wd;
513+
/* this either matches fsnotify_find_mark_entry, or init_mark_entry
514+
* depending on which path we took... */
515+
fsnotify_put_mark(entry);
516+
517+
return ret;
512518

513519
out_err:
514520
/* see this isn't supposed to happen, just kill the watch */

0 commit comments

Comments
 (0)