From: Michael Ellerman <mpe@ellerman.id.au>
To: Daniel Axtens <dja@axtens.net>,
linux-kernel@vger.kernel.org, viro@zeniv.linux.org.uk
Cc: akash.goel@intel.com, ajd@linux.ibm.com,
Daniel Axtens <dja@axtens.net>,
syzbot+1e925b4b836afe85a1c6@syzkaller-ppc64.appspotmail.com,
syzbot+587b2421926808309d21@syzkaller-ppc64.appspotmail.com,
syzbot+58320b7171734bf79d26@syzkaller.appspotmail.com,
syzbot+d6074fb08bdb2e010520@syzkaller.appspotmail.com
Subject: Re: [PATCH] relay: handle alloc_percpu returning NULL in relay_open
Date: Fri, 29 Nov 2019 15:59:27 +1100 [thread overview]
Message-ID: <87d0dbffbk.fsf@mpe.ellerman.id.au> (raw)
In-Reply-To: <20191129013745.7168-1-dja@axtens.net>
Daniel Axtens <dja@axtens.net> writes:
> 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. Because we can readily catch and
> handle this situation, switch to alloc_cpu_gfp and pass in __GFP_NOWARN.
>
> 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@syzkaller-ppc64.appspotmail.com
> Reported-by: syzbot+587b2421926808309d21@syzkaller-ppc64.appspotmail.com
> Reported-by: syzbot+58320b7171734bf79d26@syzkaller.appspotmail.com
> Reported-by: syzbot+d6074fb08bdb2e010520@syzkaller.appspotmail.com
> Cc: Akash Goel <akash.goel@intel.com>
> Cc: Andrew Donnellan <ajd@linux.ibm.com> # syzkaller-ppc64
> Cc: stable@vger.kernel.org # v4.10+
> Signed-off-by: Daniel Axtens <dja@axtens.net>
...
> diff --git a/kernel/relay.c b/kernel/relay.c
> index ade14fb7ce2e..a376cc6b54ec 100644
> --- a/kernel/relay.c
> +++ b/kernel/relay.c
> @@ -580,7 +580,13 @@ struct rchan *relay_open(const char *base_filename,
> if (!chan)
> return NULL;
>
> - chan->buf = alloc_percpu(struct rchan_buf *);
> + chan->buf = alloc_percpu_gfp(struct rchan_buf *,
> + GFP_KERNEL | __GFP_NOWARN);
> + if (!chan->buf) {
> + kfree(chan);
> + return NULL;
> + }
> +
> chan->version = RELAYFS_CHANNEL_VERSION;
> chan->n_subbufs = n_subbufs;
> chan->subbuf_size = subbuf_size;
This looks right to me. The kfree + direct return is correct, there's
nothing else that needs tear down in this function.
I think I'm 50/50 on the __GFP_NOWARN. We're only asking for 8 bytes per
cpu, and if that fails the system is pretty sick, so a warning could be
helpful. There's also logic in the percpu allocator to limit the number
of warnings printed. But see what others think.
Reviewed-by: Michael Ellerman <mpe@ellerman.id.au>
cheers
next prev parent reply other threads:[~2019-11-29 4:59 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-29 1:37 [PATCH] relay: handle alloc_percpu returning NULL in relay_open Daniel Axtens
2019-11-29 4:59 ` Michael Ellerman [this message]
2019-11-29 12:42 ` Andrew Donnellan
2019-11-30 6:04 ` Daniel Axtens
2019-12-23 16:36 ` Guenter Roeck
2019-12-24 0:26 ` Daniel Axtens
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87d0dbffbk.fsf@mpe.ellerman.id.au \
--to=mpe@ellerman.id.au \
--cc=ajd@linux.ibm.com \
--cc=akash.goel@intel.com \
--cc=dja@axtens.net \
--cc=linux-kernel@vger.kernel.org \
--cc=syzbot+1e925b4b836afe85a1c6@syzkaller-ppc64.appspotmail.com \
--cc=syzbot+58320b7171734bf79d26@syzkaller.appspotmail.com \
--cc=syzbot+587b2421926808309d21@syzkaller-ppc64.appspotmail.com \
--cc=syzbot+d6074fb08bdb2e010520@syzkaller.appspotmail.com \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.