From 76385377c8aaaaf548b80cdba5a40ae482067f4c Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 10 Mar 2020 20:06:36 +0800 Subject: [PATCH] relay: handle alloc_percpu returning NULL in relay_open hulk inclusion category: bugfix bugzilla: 13690 CVE: CVE-2019-19462 ------------------------------------------------- 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 [c0000000003f3fec] relay_open+0x29c/0x600 LR [c0000000003f3fc0] relay_open+0x270/0x600 Call Trace: [c000000054353a70] [c0000000003f3fb4] relay_open+0x264/0x600 (unreliable) [c000000054353b00] [c000000000451764] __blk_trace_setup+0x254/0x600 [c000000054353bb0] [c000000000451b78] blk_trace_setup+0x68/0xa0 [c000000054353c10] [c0000000010da77c] sg_ioctl+0x7bc/0x2e80 [c000000054353cd0] [c000000000758cbc] do_vfs_ioctl+0x13c/0x1300 [c000000054353d90] [c000000000759f14] ksys_ioctl+0x94/0x130 [c000000054353de0] [c000000000759ff8] sys_ioctl+0x48/0xb0 [c000000054353e20] [c00000000000bcd0] 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. https://lore.kernel.org/lkml/20191219121256.26480-1-dja%40axtens.net/ Fixes: 017c59c042d0 ("relay: Use per CPU constructs for the relay channel buffer pointers") Signed-off-by: Yang Yingliang Reviewed-by: Hanjun Guo Signed-off-by: Yang Yingliang --- kernel/relay.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/relay.c b/kernel/relay.c index 9e0f52375487..078f733bebae 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -581,6 +581,10 @@ 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; -- GitLab