On 2/18/26 7:15 PM, Alexei Starovoitov wrote:
On Wed, Feb 18, 2026 at 2:44 AM Slava Imameev
<[email protected]> wrote:

- This programs cannot be compiled as bpf_core_cast cannot cast to a
multi-level pointer:

SEC("lsm/sb_eat_lsm_opts")
int BPF_PROG(sb_eat_lsm_opts_1,char *options, void **mnt_opts)
{
     void** ppt = bpf_core_cast(mnt_opts, void*);
     bpf_printk("%p\t", *ppt);
     return 0;
}
Looks like there is a bug in llvm, since it crashes on the above.
But the following works:

void** ppt = bpf_rdonly_cast(mnt_opts, 0);
bpf_printk("%lx\t", *ppt);

Plus Eduard's diff:
-       if (is_void_or_int_ptr(btf, t))
+       if (is_void_or_int_ptr(btf, t) || !btf_type_is_struct_ptr(btf, t))


- There is a workaround, which requires introducing a wrapper for
a pointer or typedef:

struct pvoid {
     void* v;
};
llvm should have handled it without the workaround. It's a bug
that should be fixed.

Okay, I will take a look.


I think there are no technical restrictions for treating single
level pointers as PTR_TO_MEM.
I think it will be a missed opportunity and a potential foot gun.

We didn't support access to 'char *' initially.
Later relaxed it to mean that it's a valid pointer to a single byte,
but since the code is generic it also became the case
that 'char *' is allowed in kfunc and the verifier checks
that one valid byte is there.
That was a bad footgun, since we saw several cases of broken
kfunc implementations that assume that 'char *' means a string.

There are only two lsm hooks that pass 'struct foo **'.
If we make it ptr_to_mem of 8 bytes we lose the ability to do
something smarter in the future.
I think we better add support to annotate such '**' as an actual
array with given size and track types completely, so
'struct foo * var[N]' will become array_to_ptr_to_btf_id.
That's probably more work that you signed up to do,
so I suggest treating 'void **' as a scalar as Eduard suggested.
This particular sb_eat_lsm_opts() hook
doesn't have a useful type behind it anyway.
I'm less certain about 'char **'. If we make it scalar too
it will be harder to make it a pointer to nul terminated string later.

So I would do 'void **' -> scalar for now only.


Reply via email to