[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAHk-=wj=u+nttmd1huNES2U=9nePtmk7WgR8cMLCYS8wc=rhdA@mail.gmail.com>
Date: Wed, 13 May 2020 12:11:27 -0700
From: Linus Torvalds <torvalds@...ux-foundation.org>
To: Christoph Hellwig <hch@....de>
Cc: "the arch/x86 maintainers" <x86@...nel.org>,
Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
Masami Hiramatsu <mhiramat@...nel.org>,
Andrew Morton <akpm@...ux-foundation.org>,
linux-parisc@...r.kernel.org,
linux-um <linux-um@...ts.infradead.org>,
Netdev <netdev@...r.kernel.org>, bpf@...r.kernel.org,
Linux-MM <linux-mm@...ck.org>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH 11/18] maccess: remove strncpy_from_unsafe
On Wed, May 13, 2020 at 9:01 AM Christoph Hellwig <hch@....de> wrote:
>
> +static void bpf_strncpy(char *buf, long unsafe_addr)
> +{
> + buf[0] = 0;
> + if (strncpy_from_kernel_nofault(buf, (void *)unsafe_addr,
> + BPF_STRNCPY_LEN))
> + strncpy_from_user_nofault(buf, (void __user *)unsafe_addr,
> + BPF_STRNCPY_LEN);
> +}
This seems buggy when I look at it.
It seems to think that strncpy_from_kernel_nofault() returns an error code.
Not so, unless I missed where you changed the rules.
It returns the length of the string for a successful copy. 0 is
actually an error case (for count being <= 0).
So the test for success seems entirely wrong.
Also, I do wonder if we shouldn't gate this on TASK_SIZE, and do the
user trial first. On architectures where this thing is valid in the
first place (ie kernel and user addresses are separate), the test for
address size would allow us to avoid a pointless fault due to an
invalid kernel access to user space.
So I think this function should look something like
static void bpf_strncpy(char *buf, long unsafe_addr)
{
/* Try user address */
if (unsafe_addr < TASK_SIZE) {
void __user *ptr = (void __user *)unsafe_addr;
if (strncpy_from_user_nofault(buf, ptr, BPF_STRNCPY_LEN) >= 0)
return;
}
/* .. fall back on trying kernel access */
buf[0] = 0;
strncpy_from_kernel_nofault(buf, (void *)unsafe_addr,
BPF_STRNCPY_LEN);
}
or similar. No?
Linus
Powered by blists - more mailing lists