All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexei Starovoitov <alexei.starovoitov@gmail.com>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Daniel Xu <dxu@dxuuu.xyz>, bpf <bpf@vger.kernel.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	kernel-team@fb.com
Subject: Re: [PATCH bpf v5 1/2] lib/strncpy_from_user.c: Don't overcopy bytes after NUL terminator
Date: Fri, 13 Nov 2020 11:17:51 -0800	[thread overview]
Message-ID: <20201113191751.rwgv2gyw5dblhe3j@ast-mbp> (raw)
In-Reply-To: <CAHk-=wjNv9z6-VOFhpYbXb_7ePvsfQnjsH5ipUJJ6_KPe1PWVA@mail.gmail.com>

On Fri, Nov 13, 2020 at 10:08:02AM -0800, Linus Torvalds wrote:
> On Fri, Nov 13, 2020 at 9:03 AM Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> >
> > Linus,
> > I think you might have an opinion about it.
> > Please see commit log for the reason we need this fix.
> 
> Why is BPF doing this?
> 
> The thing is, if you care about the data after the strncpy, you should
> be clearing it yourself.
> 
> The kernel "strncpy_from_user()" is  *NOT* the same as "strncpy()",
> despite the name. It never has been, and it never will be. Just the
> return value being different should have given it away.
> 
> In particular, "strncpy()" is documented to zero-pad the end of the
> area. strncpy_from_user() in contrast, is documented to NOT do that.
> You cannot - and must not - depend on it.
> 
> If you want the zero-padding, you need to do it yourself. We're not
> slowing down strncpy_from_user() because you want it, because NOBODY
> ELSE cares, and you're depending on semantics that do not exist, and
> have never existed.
> 
> So if you want padding, you do something like
> 
>    long strncpy_from_user_pad(char *dst, const char __user *src, long count)
>    {
>          long res = strncpy_from_user(dst, src, count)
>          if (res >= 0)
>                 memset(dst+res, 0, count-res);
>         return res;
>    }
> 
> because BPF is doing things wrong as-is, and the problem is very much
> that BPF is relying on undefined data *after* the string.
> 
> And again - we're not slowing down the good cases just because BPF
> depends on bad behavior.

You misunderstood.
BPF side does not depend on zero padding.
The destination buffer was already initialized with zeros before the call.
What BPF didn't expect is strncpy_from_user() copying extra garbage after NUL byte.
I bet some kernel routine would be equally surprised by such behavior.
Hence I still think the fix belongs in this function.
I think the theoretical performance degradation is exactly theoretical.
The v4 approach preserves performance. It wasn't switching to byte_at_a_time:
https://patchwork.kernel.org/project/netdevbpf/patch/4ff12d0c19de63e7172d25922adfb83ae7c8691f.1604620776.git.dxu@dxuuu.xyz/
but it caused KASAN splats, since kernel usage of strncpy_from_user()
doesn't init dest array unlike bpf does.

  reply	other threads:[~2020-11-13 19:17 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-11 22:45 [PATCH bpf v5 0/2] Fix bpf_probe_read_user_str() overcopying Daniel Xu
2020-11-11 22:45 ` [PATCH bpf v5 1/2] lib/strncpy_from_user.c: Don't overcopy bytes after NUL terminator Daniel Xu
2020-11-11 23:20   ` Andrii Nakryiko
2020-11-13 17:03   ` Alexei Starovoitov
2020-11-13 18:08     ` Linus Torvalds
2020-11-13 19:17       ` Alexei Starovoitov [this message]
2020-11-13 19:29         ` Linus Torvalds
2020-11-13 19:46         ` Linus Torvalds
2020-11-13 20:10         ` Linus Torvalds
2020-11-13 20:57           ` Alexei Starovoitov
2020-11-13 21:14             ` Linus Torvalds
2020-11-11 22:45 ` [PATCH bpf v5 2/2] selftest/bpf: Test bpf_probe_read_user_str() strips trailing bytes after NUL Daniel Xu
2020-11-11 23:22 ` [PATCH bpf v5 0/2] Fix bpf_probe_read_user_str() overcopying Andrii Nakryiko
2020-11-12 19:10   ` Daniel Xu
2020-11-12 19:24     ` Andrii Nakryiko

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=20201113191751.rwgv2gyw5dblhe3j@ast-mbp \
    --to=alexei.starovoitov@gmail.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=dxu@dxuuu.xyz \
    --cc=kernel-team@fb.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /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.