[PATCH 1/1] kernel/relay.c: handle alloc_percpu returning NULL in relay_open
Benjamin M Romer
benjamin.romer at canonical.com
Tue Jun 9 02:46:43 UTC 2020
From: Daniel Axtens <dja at axtens.net>
alloc_percpu() may return NULL, which means chan->buf may be set to NULL.
In that case, when we do *per_cpu_ptr(chan->buf, ...), we dereference an
invalid pointer:
BUG: Unable to handle kernel data access at 0x7dae0000
Faulting instruction address: 0xc0000000003f3fec
...
NIP relay_open+0x29c/0x600
LR relay_open+0x270/0x600
Call Trace:
relay_open+0x264/0x600 (unreliable)
__blk_trace_setup+0x254/0x600
blk_trace_setup+0x68/0xa0
sg_ioctl+0x7bc/0x2e80
do_vfs_ioctl+0x13c/0x1300
ksys_ioctl+0x94/0x130
sys_ioctl+0x48/0xb0
system_call+0x5c/0x68
Check if alloc_percpu returns NULL.
This was found by syzkaller both on x86 and powerpc, and the reproducer
it found on powerpc is capable of hitting the issue as an unprivileged
user.
Fixes: 017c59c042d0 ("relay: Use per CPU constructs for the relay channel buffer pointers")
Reported-by: syzbot+1e925b4b836afe85a1c6 at syzkaller-ppc64.appspotmail.com
Reported-by: syzbot+587b2421926808309d21 at syzkaller-ppc64.appspotmail.com
Reported-by: syzbot+58320b7171734bf79d26 at syzkaller.appspotmail.com
Reported-by: syzbot+d6074fb08bdb2e010520 at syzkaller.appspotmail.com
Signed-off-by: Daniel Axtens <dja at axtens.net>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
Reviewed-by: Michael Ellerman <mpe at ellerman.id.au>
Reviewed-by: Andrew Donnellan <ajd at linux.ibm.com>
Acked-by: David Rientjes <rientjes at google.com>
Cc: Akash Goel <akash.goel at intel.com>
Cc: Andrew Donnellan <ajd at linux.ibm.com>
Cc: Guenter Roeck <linux at roeck-us.net>
Cc: Salvatore Bonaccorso <carnil at debian.org>
Cc: <stable at vger.kernel.org> [4.10+]
Link: http://lkml.kernel.org/r/20191219121256.26480-1-dja@axtens.net
Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
(cherry picked from commit 54e200ab40fc14c863bcc80a51e20b7906608fce)
CVE-2019-19642
Signed-off-by: Benjamin M Romer <benjamin.romer at canonical.com>
---
kernel/relay.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/kernel/relay.c b/kernel/relay.c
index ade14fb7ce2e..4b760ec16342 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -581,6 +581,11 @@ struct rchan *relay_open(const char *base_filename,
return NULL;
chan->buf = alloc_percpu(struct rchan_buf *);
+ if (!chan->buf) {
+ kfree(chan);
+ return NULL;
+ }
+
chan->version = RELAYFS_CHANNEL_VERSION;
chan->n_subbufs = n_subbufs;
chan->subbuf_size = subbuf_size;
--
2.25.1
More information about the kernel-team
mailing list