diff options
| author | Chia-Ming Chang <chiamingc@synology.com> | 2026-02-24 12:34:42 +0300 |
|---|---|---|
| committer | Jan Kara <jack@suse.cz> | 2026-02-26 17:11:50 +0300 |
| commit | 6a320935fa4293e9e599ec9f85dc9eb3be7029f8 (patch) | |
| tree | 9d9c0c5518a1dec44f60f2ac149576290a26ea97 | |
| parent | f4d0ec0aa20d49f09dc01d82894ce80d72de0560 (diff) | |
| download | linux-6a320935fa4293e9e599ec9f85dc9eb3be7029f8.tar.xz | |
inotify: fix watch count leak when fsnotify_add_inode_mark_locked() fails
When fsnotify_add_inode_mark_locked() fails in inotify_new_watch(),
the error path calls inotify_remove_from_idr() but does not call
dec_inotify_watches() to undo the preceding inc_inotify_watches().
This leaks a watch count, and repeated failures can exhaust the
max_user_watches limit with -ENOSPC even when no watches are active.
Prior to commit 1cce1eea0aff ("inotify: Convert to using per-namespace
limits"), the watch count was incremented after fsnotify_add_mark_locked()
succeeded, so this path was not affected. The conversion moved
inc_inotify_watches() before the mark insertion without adding the
corresponding rollback.
Add the missing dec_inotify_watches() call in the error path.
Fixes: 1cce1eea0aff ("inotify: Convert to using per-namespace limits")
Cc: stable@vger.kernel.org
Signed-off-by: Chia-Ming Chang <chiamingc@synology.com>
Signed-off-by: robbieko <robbieko@synology.com>
Reviewed-by: Nikolay Borisov <nik.borisov@suse.com>
Link: https://patch.msgid.link/20260224093442.3076294-1-chiamingc@synology.com
Signed-off-by: Jan Kara <jack@suse.cz>
| -rw-r--r-- | fs/notify/inotify/inotify_user.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 5e1845f2c25d..2edac3b39178 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -621,6 +621,7 @@ static int inotify_new_watch(struct fsnotify_group *group, if (ret) { /* we failed to get on the inode, get off the idr */ inotify_remove_from_idr(group, tmp_i_mark); + dec_inotify_watches(group->inotify_data.ucounts); goto out_err; } |
