All of lore.kernel.org
 help / color / mirror / Atom feed
From: Shung-Hsi Yu <shung-hsi.yu@suse.com>
To: Eduard Zingerman <eddyz87@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>,
	bpf@vger.kernel.org, ast@kernel.org, andrii@kernel.org,
	kernel-team@fb.com, yhs@fb.com, john.fastabend@gmail.com
Subject: Re: [PATCH bpf-next 1/2] bpf: propagate nullness information for reg to reg comparisons
Date: Thu, 1 Sep 2022 17:01:24 +0800	[thread overview]
Message-ID: <YxB05NCEbNWVYslz@syu-laptop> (raw)
In-Reply-To: <YxBpoj/MYrBlUJ8h@syu-laptop>

On Thu, Sep 01, 2022 at 04:13:22PM +0800, Shung-Hsi Yu wrote:
> On Tue, Aug 30, 2022 at 01:41:28PM +0300, Eduard Zingerman wrote:
> > Hi Daniel,
> > 
> > Thank you for commenting.
> > 
> > > On Mon, 2022-08-29 at 16:23 +0200, Daniel Borkmann wrote:
> > > [...]
> > > >   kernel/bpf/verifier.c | 41 +++++++++++++++++++++++++++++++++++++++--
> > > >   1 file changed, 39 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > > > index 0194a36d0b36..7585288e035b 100644
> > > > --- a/kernel/bpf/verifier.c
> > > > +++ b/kernel/bpf/verifier.c
> > > > @@ -472,6 +472,11 @@ static bool type_may_be_null(u32 type)
> > > >   	return type & PTR_MAYBE_NULL;
> > > >   }
> > > >   
> > > > +static bool type_is_pointer(enum bpf_reg_type type)
> > > > +{
> > > > +	return type != NOT_INIT && type != SCALAR_VALUE;
> > > > +}
> > > 
> > > We also have is_pointer_value(), semantics there are a bit different (and mainly to
> > > prevent leakage under unpriv), but I wonder if this can be refactored to accommodate
> > > both. My worry is that if in future we extend one but not the other bugs might slip
> > > in.
> > 
> > John was concerned about this as well, guess I won't not dodging it :)
> > Suppose I do the following modification:
> > 
> >     static bool type_is_pointer(enum bpf_reg_type type)
> >     {
> >     	return type != NOT_INIT && type != SCALAR_VALUE;
> >     }
> >     
> >     static bool __is_pointer_value(bool allow_ptr_leaks,
> >     			       const struct bpf_reg_state *reg)
> >     {
> >     	if (allow_ptr_leaks)
> >     		return false;
> > 
> > -    	return reg->type != SCALAR_VALUE;
> > +    	return type_is_pointer(reg->type);
> >     }
>      
> The verifier is using the wrapped is_pointer_value() to guard against
> pointer leak.
> 
>   static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regno,
>   			    int off, int bpf_size, enum bpf_access_type t,
>   			    int value_regno, bool strict_alignment_once)
>   {
>       ...
>   	if (reg->type == PTR_TO_MAP_KEY) {
>   		...
>   	} else if (reg->type == PTR_TO_MAP_VALUE) {
>   		struct bpf_map_value_off_desc *kptr_off_desc = NULL;
>   
>   		if (t == BPF_WRITE && value_regno >= 0 &&
>   		    is_pointer_value(env, value_regno)) {
>   			verbose(env, "R%d leaks addr into map\n", value_regno);
>   			return -EACCES;
>           ...
>   	}
>       ...
>   }
> 
> In the check_mem_access() case the semantic of is_pointer_value() is check
> whether or not the value *might* be a pointer, and since NON_INIT can be
> potentially anything, it should not be excluded.

I wasn't reading the threads carefully enough, apologies, just realized
Daniel had already mention the above point further up.

Also, after going back to the previous RFC thread I saw John mention that
after making the is_pointer_value() changes to exclude NOT_INIT, the tests
still passes.

I guess that comes down to how the verifier rigorously check that the
registers are not NOT_INIT using check_reg_arg(..., SRC_OP), before moving
on to more specific checks. So I'm a bit less sure about the split
{maybe,is}_pointer_value() approach proposed below now.

> Since the use case seems different, perhaps we could split them up, e.g. a
> maybe_pointer_value() and a is_pointer_value(), or something along that
> line.
> 
> The former is equivalent to type != SCALAR_VALUE, and the latter equivalent
> to type != NOT_INIT && type != SCALAR_VALUE. The latter can be used here for
> implementing nullness propogation.
> 
> > And check if there are test cases that have to be added because of the
> > change in the __is_pointer_value behavior (it does not check for
> > `NOT_INIT` right now). Does this sound like a plan?
> > 
> > [...]
> > > Could we consolidate the logic above with the one below which deals with R == 0 checks?
> > > There are some similarities, e.g. !is_jmp32, both test for jeq/jne and while one is based
> > > on K, the other one on X, though we could also add check X == 0 for below. Anyway, just
> > > a though that it may be nice to consolidate the handling.
> > 
> > Ok, I will try to consolidate those.
> > 
> > Thanks,
> > Eduard

  reply	other threads:[~2022-09-01  9:03 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-26 17:29 [PATCH bpf-next 0/2] propagate nullness information for reg to reg comparisons Eduard Zingerman
2022-08-26 17:29 ` [PATCH bpf-next 1/2] bpf: " Eduard Zingerman
2022-08-29 14:23   ` Daniel Borkmann
2022-08-30 10:41     ` Eduard Zingerman
2022-09-01  8:13       ` Shung-Hsi Yu
2022-09-01  9:01         ` Shung-Hsi Yu [this message]
2022-10-27 22:18           ` Eduard Zingerman
2022-08-26 17:29 ` [PATCH bpf-next 2/2] selftests/bpf: check nullness propagation " Eduard Zingerman
2022-11-14 18:01   ` Alexei Starovoitov
2022-11-15 20:31     ` Eduard Zingerman
2022-11-15 20:51       ` Alexei Starovoitov

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=YxB05NCEbNWVYslz@syu-laptop \
    --to=shung-hsi.yu@suse.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=john.fastabend@gmail.com \
    --cc=kernel-team@fb.com \
    --cc=yhs@fb.com \
    /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.