Re: [PATCH bpf-next 10/10] bpf: consistenly use program's recorded capabilities in BPF verifier

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, May 4, 2023 at 3:51 PM Andrii Nakryiko
<andrii.nakryiko@xxxxxxxxx> wrote:
>
> On Thu, May 4, 2023 at 3:20 PM Alexei Starovoitov
> <alexei.starovoitov@xxxxxxxxx> wrote:
> >
> > On Tue, May 02, 2023 at 04:06:19PM -0700, Andrii Nakryiko wrote:
> > > diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> > > index 4d057d39c286..c0d60da7e0e0 100644
> > > --- a/kernel/bpf/core.c
> > > +++ b/kernel/bpf/core.c
> > > @@ -661,7 +661,7 @@ static bool bpf_prog_kallsyms_candidate(const struct bpf_prog *fp)
> > >  void bpf_prog_kallsyms_add(struct bpf_prog *fp)
> > >  {
> > >       if (!bpf_prog_kallsyms_candidate(fp) ||
> > > -         !bpf_capable())
> > > +         !fp->aux->bpf_capable)
> > >               return;
> >
> > Looking at this bit made me worry about classic bpf.
> > bpf_prog_alloc_no_stats() zeros all fields include aux->bpf_capable.
> > And loading of classic progs doesn't go through bpf_check().
> > So fp->aux->bpf_capable will stay 'false' even when root loads cBPF.
> > It doesn't matter here, since bpf_prog_kallsyms_candidate() will return false
> > for cBPF.
> >
> > Maybe we should init aux->bpf_capable in bpf_prog_alloc_no_stats()
> > to stay consistent between cBPF and eBPF ?

I'd like to avoid doing this deep inside bpf_prog_alloc_no_stats() or
bpf_prog_alloc() because this decision about privileges will be later
based on some other factors besides CAP_BPF. So hard-coding
bpf_capable() here defeats the purpose.

I did look at classic BPF, there are three places in net/core/filter.c
where we allocated struct bpf_prog from  struct sock_fprog/struct
sock_fprog_kern: bpf_prog_create, bpf_prog_create_from_user,
__get_filter.

Would it be ok if I just hard-coded `prog->aux->bpf_capable =
bpf_capable();` (and same for perfmon) in those three functions? Or
leave them always false? Because taking a step back a bit, do we want
to allow privileged classic BPF programs at all? Maybe it's actually
good that we force those cBPF programs to be unprivileged?

Right now it doesn't even matter, I think, because these privileges
are only checked during verification. But assuming that in the future
we might want to check that at runtime from helpers/kfuncs, probably
best to have a strategy here.

Tl;dr, I don't know what's the best approach to take, but just calling
into bpf_capable() deeply inside bpf_prog_alloc/bpf_prog_alloc_stats
makes subsequent work to implement trusted unpriv harder. Thoughts?

> > It probably has no effect, but anyone looking at crash dumps with drgn
> > will have a consistent view of aux->bpf_capable field.
>
> classic BPF predates my involvement with BPF, so I didn't even think
> about that. I'll check and make sure we do initialize aux->bpf_capable
> for that





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux