All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] watch_queue: A couple more fixes
@ 2022-03-21 13:00 David Howells
  2022-03-21 13:00 ` [PATCH 1/2] watch_queue: Fix NULL dereference in error cleanup David Howells
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: David Howells @ 2022-03-21 13:00 UTC (permalink / raw)
  To: torvalds; +Cc: dhowells, fmdefrancesco, jannh, keyrings, linux-kernel


Hi Linus,

Here are fixes for a couple more watch_queue bugs, both found by syzbot:

 (1) 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.

 (2) Fix a missing kfree in free_watch() to actually free the watch[3].

Both have syzbot reproducers.

The fixes are also available through git:

	https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-fixes

David

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]
---
David Howells (2):
      watch_queue: Fix NULL dereference in error cleanup
      watch_queue: Actually free the watch


 kernel/watch_queue.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] watch_queue: Fix NULL dereference in error cleanup
  2022-03-21 13:00 [PATCH 0/2] watch_queue: A couple more fixes David Howells
@ 2022-03-21 13:00 ` David Howells
  2022-03-21 13:00 ` [PATCH 2/2] watch_queue: Actually free the watch David Howells
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: David Howells @ 2022-03-21 13:00 UTC (permalink / raw)
  To: torvalds; +Cc: dhowells, fmdefrancesco, jannh, keyrings, linux-kernel

In watch_queue_set_size(), the error cleanup code doesn't take account of
the fact that __free_page() can't handle a NULL pointer when trying to free
up buffer pages that did get allocated.

Fix this by only calling __free_page() on the pages actually allocated.

Without the fix, this can lead to something like the following:

BUG: KASAN: null-ptr-deref in __free_pages+0x1f/0x1b0 mm/page_alloc.c:5473
Read of size 4 at addr 0000000000000034 by task syz-executor168/3599
...
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:88 [inline]
 dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106
 __kasan_report mm/kasan/report.c:446 [inline]
 kasan_report.cold+0x66/0xdf mm/kasan/report.c:459
 check_region_inline mm/kasan/generic.c:183 [inline]
 kasan_check_range+0x13d/0x180 mm/kasan/generic.c:189
 instrument_atomic_read include/linux/instrumented.h:71 [inline]
 atomic_read include/linux/atomic/atomic-instrumented.h:27 [inline]
 page_ref_count include/linux/page_ref.h:67 [inline]
 put_page_testzero include/linux/mm.h:717 [inline]
 __free_pages+0x1f/0x1b0 mm/page_alloc.c:5473
 watch_queue_set_size+0x499/0x630 kernel/watch_queue.c:275
 pipe_ioctl+0xac/0x2b0 fs/pipe.c:632
 vfs_ioctl fs/ioctl.c:51 [inline]
 __do_sys_ioctl fs/ioctl.c:874 [inline]
 __se_sys_ioctl fs/ioctl.c:860 [inline]
 __x64_sys_ioctl+0x193/0x200 fs/ioctl.c:860
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x44/0xae

Fixes: c73be61cede5 ("pipe: Add general notification queue support")
Reported-and-tested-by: syzbot+d55757faa9b80590767b@syzkaller.appspotmail.com
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Fabio M. De Francesco <fmdefrancesco@gmail.com>
---

 kernel/watch_queue.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
index 00703444a219..5848d4795816 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:



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] watch_queue: Actually free the watch
  2022-03-21 13:00 [PATCH 0/2] watch_queue: A couple more fixes David Howells
  2022-03-21 13:00 ` [PATCH 1/2] watch_queue: Fix NULL dereference in error cleanup David Howells
@ 2022-03-21 13:00 ` David Howells
  2022-03-22  4:00 ` [PATCH 0/2] watch_queue: A couple more fixes Linus Torvalds
  2022-03-22  9:55 ` David Howells
  3 siblings, 0 replies; 5+ messages in thread
From: David Howells @ 2022-03-21 13:00 UTC (permalink / raw)
  To: torvalds; +Cc: dhowells, fmdefrancesco, jannh, keyrings, linux-kernel

free_watch() does everything barring actually freeing the watch object.  Fix
this by adding the missing kfree.

kmemleak produces a report something like the following.  Note that as an
address can be seen in the first word, the watch would appear to have gone
through call_rcu().

BUG: memory leak
unreferenced object 0xffff88810ce4a200 (size 96):
  comm "syz-executor352", pid 3605, jiffies 4294947473 (age 13.720s)
  hex dump (first 32 bytes):
    e0 82 48 0d 81 88 ff ff 00 00 00 00 00 00 00 00  ..H.............
    80 a2 e4 0c 81 88 ff ff 00 00 00 00 00 00 00 00  ................
  backtrace:
    [<ffffffff8214e6cc>] kmalloc include/linux/slab.h:581 [inline]
    [<ffffffff8214e6cc>] kzalloc include/linux/slab.h:714 [inline]
    [<ffffffff8214e6cc>] keyctl_watch_key+0xec/0x2e0 security/keys/keyctl.c:1800
    [<ffffffff8214ec84>] __do_sys_keyctl+0x3c4/0x490 security/keys/keyctl.c:2016
    [<ffffffff84493a25>] do_syscall_x64 arch/x86/entry/common.c:50 [inline]
    [<ffffffff84493a25>] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
    [<ffffffff84600068>] entry_SYSCALL_64_after_hwframe+0x44/0xae

Fixes: c73be61cede5 ("pipe: Add general notification queue support")
Reported-and-tested-by: syzbot+6e2de48f06cdb2884bfc@syzkaller.appspotmail.com
Signed-off-by: David Howells <dhowells@redhat.com>
---

 kernel/watch_queue.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
index 5848d4795816..3990e4df3d7b 100644
--- a/kernel/watch_queue.c
+++ b/kernel/watch_queue.c
@@ -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)



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/2] watch_queue: A couple more fixes
  2022-03-21 13:00 [PATCH 0/2] watch_queue: A couple more fixes David Howells
  2022-03-21 13:00 ` [PATCH 1/2] watch_queue: Fix NULL dereference in error cleanup David Howells
  2022-03-21 13:00 ` [PATCH 2/2] watch_queue: Actually free the watch David Howells
@ 2022-03-22  4:00 ` Linus Torvalds
  2022-03-22  9:55 ` David Howells
  3 siblings, 0 replies; 5+ messages in thread
From: Linus Torvalds @ 2022-03-22  4:00 UTC (permalink / raw)
  To: David Howells
  Cc: Fabio M. De Francesco, Jann Horn, keyrings, Linux Kernel Mailing List

On Mon, Mar 21, 2022 at 6:01 AM David Howells <dhowells@redhat.com> wrote:
>
> The fixes are also available through git:
>
>         https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/log/?h=keys-fixes

You have the dubious distinction of being the second pull today that
didn't use a signed tag.

Of 46 pulls today, only two were untagged branches, with the rest
using signed tags.

              Linus

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/2] watch_queue: A couple more fixes
  2022-03-21 13:00 [PATCH 0/2] watch_queue: A couple more fixes David Howells
                   ` (2 preceding siblings ...)
  2022-03-22  4:00 ` [PATCH 0/2] watch_queue: A couple more fixes Linus Torvalds
@ 2022-03-22  9:55 ` David Howells
  3 siblings, 0 replies; 5+ messages in thread
From: David Howells @ 2022-03-22  9:55 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: dhowells, Fabio M. De Francesco, Jann Horn, keyrings,
	Linux Kernel Mailing List

Linus Torvalds <torvalds@linux-foundation.org> wrote:

> You have the dubious distinction of being the second pull today that
> didn't use a signed tag.

It wasn't my intention to ask you to pull it at this time, but rather put it
up for review.  With hindsight, I should probably have stuck an "RFC" flag on
the cover.

David


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-03-22  9:55 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-21 13:00 [PATCH 0/2] watch_queue: A couple more fixes David Howells
2022-03-21 13:00 ` [PATCH 1/2] watch_queue: Fix NULL dereference in error cleanup David Howells
2022-03-21 13:00 ` [PATCH 2/2] watch_queue: Actually free the watch David Howells
2022-03-22  4:00 ` [PATCH 0/2] watch_queue: A couple more fixes Linus Torvalds
2022-03-22  9:55 ` David Howells

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.