lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <ZAErLAKYKZKqmhSi@maniforge>
Date:   Thu, 2 Mar 2023 17:03:08 -0600
From:   David Vernet <void@...ifault.com>
To:     Alexei Starovoitov <alexei.starovoitov@...il.com>
Cc:     davem@...emloft.net, daniel@...earbox.net, andrii@...nel.org,
        martin.lau@...nel.org, davemarchevsky@...a.com, tj@...nel.org,
        memxor@...il.com, netdev@...r.kernel.org, bpf@...r.kernel.org,
        kernel-team@...com
Subject: Re: [PATCH v4 bpf-next 6/6] bpf: Refactor RCU enforcement in the
 verifier.

On Thu, Mar 02, 2023 at 01:23:44PM -0800, Alexei Starovoitov wrote:

[...]

> > > +		if (type_is_trusted(env, reg, off)) {
> > > +			flag |= PTR_TRUSTED;
> > > +		} else if (in_rcu_cs(env) && !type_may_be_null(reg->type)) {
> > > +			if (type_is_rcu(env, reg, off)) {
> > > +				/* ignore __rcu tag and mark it MEM_RCU */
> > > +				flag |= MEM_RCU;
> > > +			} else if (flag & MEM_RCU) {
> > > +				/* __rcu tagged pointers can be NULL */
> > > +				flag |= PTR_MAYBE_NULL;
> > 
> > I'm not quite understanding the distinction between manually-specified
> > RCU-safe types being non-nullable, vs. __rcu pointers being nullable.
> > Aren't they functionally the exact same thing, with the exception being
> > that gcc doesn't support __rcu, so we've decided to instead manually
> > specify them for some types that we know we need until __rcu is the
> > default mechanism?  If the plan is to remove these macros once gcc
> > supports __rcu, this could break some programs that are expecting the
> > fields to be non-NULL, no?
> 
> BTF_TYPE_SAFE_RCU is a workaround for now.
> We can make it exactly like __rcu, but it would split
> the natural dereference of task->cgroups->dfl_cgrp into
> two derefs with extra !=NULL check in-between which is ugly and unnecessary.
> 
> > I see why we're doing this in the interim -- task->cgroups,
> > css->dfl_cgrp, task->cpus_ptr, etc can never be NULL. The problem is
> > that I think those are implementation details that are separate from the
> > pointers being RCU safe. This seems rather like we need a separate
> > non-nullable tag, or something to that effect.
> 
> Right. It is certainly an implementation detail.
> We'd need a new __not_null_mostly tag or __not_null_after_init.
> (similar to __read_mostly and __ro_after_init).
> Where non-null property is true when bpf get to see these structures.
> 
> The current allowlist is incomplete and far from perfect.
> I suspect we'd need to add a bunch more during this release cycle.
> This patch is aggressive in deprecation of old ptr_to_btf_id.
> Some breakage is expected. Hence the timing to do it right now
> at the beginning of the cycle.

Thanks for explaining. This all sounds good -- I'm certainly in favor of
being aggressive in deprecating the old ptr_to_btf_id approach. I was
really just worried that we'd break progs when we got rid of
BTF_TYPE_SAFE_RCU and started to use __rcu once gcc supported it, but as
you said we can just add another type tag at that time. And if we need
to add another RCU-safe pointer that is NULL-able before we have the gcc
support we need, we can always just add something like a
BTF_TYPE_SAFE_NULLABLE_RCU in the interim. Clearly a temporary solution,
but really not a bad one at all.

> 
> > >  		flag &= ~PTR_TRUSTED;
> > 
> > Do you know what else is left for us to fix to be able to just set
> > PTR_UNTRUSTED here?
> 
> All "ctx->" derefs. check_ctx_access() returns old school PTR_TO_BTF_ID.
> We can probably mark all of them as trusted, but need to audit a lot of code.
> I've also played with forcing helpers with ARG_PTR_TO_BTF_ID to be trusted,
> but still too much selftest breakage to even look at.
> 
> The patch also has:
> +                       if (BTF_INFO_KIND(mtype->info) == BTF_KIND_UNION &&
> +                           btf_type_vlen(mtype) != 1)
> +                               /*
> +                                * walking unions yields untrusted pointers
> +                                * with exception of __bpf_md_ptr and other
> +                                * unions with a single member
> +                                */
> +                               *flag |= PTR_UNTRUSTED;
> this is in particular to make skb->dev deref to return untrusted.
> In this past we allowed skb->dev->ifindex to go via PTR_TO_BTF_ID and PROBE_MEM.
> It's safe, but not clean. And we have no safe way to get trusted 'dev' to pass into helpers.
> It's time to clean this all up as well, but it will require rearranging fields in sk_buff.
> Lots of work ahead.

SGTM, thanks

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ