Re: [PATCH v2 2/2] x86/cfi,bpf: Fix BPF JIT call

From: Alexei Starovoitov
Date: Fri Dec 08 2023 - 15:58:18 EST


On Fri, Dec 8, 2023 at 12:52 PM Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote:
>
> On Fri, Dec 08, 2023 at 12:41:03PM -0800, Alexei Starovoitov wrote:
> > On Fri, Dec 8, 2023 at 12:35 PM Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote:
>
> > > -__bpf_kfunc void bpf_task_release(struct task_struct *p)
> > > +__bpf_kfunc void bpf_task_release(void *p)
> >
> > Yeah. That won't work. We need a wrapper.
> > Since bpf prog is also calling it directly.
> > In progs/task_kfunc_common.h
> > void bpf_task_release(struct task_struct *p) __ksym;
> >
> > than later both libbpf and the verifier check that
> > what bpf prog is calling actually matches the proto
> > of what is in the kernel.
> > Effectively we're doing strong prototype check at load time.
>
> I'm still somewhat confused on how this works, where does BPF get the
> address of the function from? and what should I call the wrapper?

It starts with
register_btf_id_dtor_kfuncs() that takes a set of btf_ids:
{btf_id_of_type, btf_id_of_dtor_function}, ...

Then based on btf_id_of_dtor_function we find its type proto, name, do checks,
and eventually:
addr = kallsyms_lookup_name(dtor_func_name);
field->kptr.dtor = (void *)addr;

bpf_task_release(struct task_struct *p) would need to stay as-is,
but we can have a wrapper
void bpf_task_release_dtor(void *p)
{
bpf_task_release(p);
}

And adjust the above lookup with extra "_dtor" suffix.

> > btw instead of EXPORT_SYMBOL_GPL(bpf_task_release)
> > can __ADDRESSABLE be used ?
> > Since it's not an export symbol.
>
> No __ADDRESSABLE() is expressly ignored, but we have IBT_NOSEAL() that
> should do it. I'll rename the thing and lift it out of x86 to avoid
> breaking all other arch builds.

Makes sense.