Re: [PATCH bpf-next v2 0/2] bpf: Add multi-level pointer parameter
From: Yonghong Song <yonghong.song@linux.dev>
Date: 2026-02-19 05:17:43
Also in:
bpf, linux-kselftest, lkml
On 2/18/26 7:15 PM, Alexei Starovoitov wrote:
On Wed, Feb 18, 2026 at 2:44 AM Slava Imameev [off-list ref] wrote:quoted
- 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))quoted
- 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.
quoted
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.