summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-03-21 20:38:53 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2022-03-21 20:38:53 -0700
commit6ca014cd2ddb5c56f962ec68f220be049fdcd7a3 (patch)
tree851ff1f4a6ae4a95d8850e6a2e6ca62dacf9b7fc
parent8565d64430f8278bea38dab0a3ab60b4e11c71e4 (diff)
parent3d8dcf278b1ee1eff1e90be848fa2237db4c07a7 (diff)
downloadlinux-6ca014cd2ddb5c56f962ec68f220be049fdcd7a3.tar.bz2
Merge branch 'keys-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull watch_queue fixes from David Howells: "Here are fixes for a couple more watch_queue bugs, both found by syzbot: - Fix error cleanup in watch_queue_set_size() where it tries to clean up all the pointers in the page list, even if they've not been allocated yet[1]. Unfortunately, __free_page() doesn't treat a NULL pointer as being "do nothing". A second report[2] looks like it's probably the same bug, but on arm64 rather than x86_64, but there's no reproducer. - Fix a missing kfree in free_watch() to actually free the watch[3]" Link: https://lore.kernel.org/r/000000000000b1807c05daad8f98@google.com/ [1] Link: https://lore.kernel.org/r/000000000000035b9c05daae8a5e@google.com/ [2] Link: https://lore.kernel.org/r/000000000000bc8eaf05dab91c63@google.com/ [3] * 'keys-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs: watch_queue: Actually free the watch watch_queue: Fix NULL dereference in error cleanup
-rw-r--r--kernel/watch_queue.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
index 00703444a219..3990e4df3d7b 100644
--- a/kernel/watch_queue.c
+++ b/kernel/watch_queue.c
@@ -271,7 +271,7 @@ long watch_queue_set_size(struct pipe_inode_info *pipe, unsigned int nr_notes)
return 0;
error_p:
- for (i = 0; i < nr_pages; i++)
+ while (--i >= 0)
__free_page(pages[i]);
kfree(pages);
error:
@@ -395,6 +395,7 @@ static void free_watch(struct rcu_head *rcu)
put_watch_queue(rcu_access_pointer(watch->queue));
atomic_dec(&watch->cred->user->nr_watches);
put_cred(watch->cred);
+ kfree(watch);
}
static void __put_watch(struct kref *kref)