Re: [PATCH bpf-next v2 1/6] bpf: Keep fault protection when merging pointer types
Eduard Zingerman <[email protected]>
| Newsgroups | org.kernel.vger.bpf |
|---|---|
| Message-ID | <[email protected]> |
On Fri, 2026-08-14 at 23:52 +0200, Daniel Borkmann wrote:
> When the same BPF_LDX instruction is reached through paths that yield
> different pointer types, save_aux_ptr_type() merges them into a single
> type which is later used by bpf_convert_ctx_accesses() to decide whether
> the load has to be rewritten into a BPF_PROBE_MEM one.
>
> Before f2362a57aeff ("bpf: allow void* cast using bpf_rdonly_cast()")
> the merge only accepted two PTR_TO_BTF_ID pointers and unconditionally
> fell back to PTR_TO_BTF_ID | PTR_UNTRUSTED, so the merged type was always
> one that gets the BPF_PROBE_MEM rewrite. However, the mentioned commit
> widened the merge to also cover a PTR_TO_MEM base and replaced the
> fallback by a union of the PTR_UNTRUSTED and MEM_RDONLY flags.
>
> A union of flags though cannot express the property the later rewrite
> is built upon, some examples:
>
> - PTR_TO_MEM merged with PTR_TO_BTF_ID | PTR_UNTRUSTED gets
> PTR_TO_MEM | PTR_UNTRUSTED but only the MEM_RDONLY variant is valid
> - PTR_TO_MEM merged with a plain PTR_TO_BTF_ID gets PTR_TO_MEM
> dropping the rewrite the latter type would have gotten
> - PTR_TO_MEM | MEM_RDONLY merged with a plain PTR_TO_BTF_ID gets
> PTR_TO_MEM | MEM_RDONLY which is not rewritten either since only
> its PTR_UNTRUSTED variant is
>
> In all three cases a program can take the unsafe path at runtime with a
> NULL or otherwise bad pointer and panic the kernel on the faulting load:
>
> BUG: kernel NULL pointer dereference, address: 0000000000000038
> RIP: 0010:bpf_prog_77531a87032eeaf1_mixed_mem_btf_id_type+0x4b/0x65
> Call Trace:
> <TASK>
> bpf_test_run+0x20b/0x460
> bpf_prog_test_run_skb+0x650/0xbe0
> __sys_bpf+0xb96/0x3140
> __x64_sys_bpf+0x2c/0x40
> do_syscall_64+0xba/0x590
> Kernel panic - not syncing: Fatal exception in interrupt
>
> Note that the last two shapes have to be fixed right here, otherwise
> the merged type retains nothing which marks the load as fault prone,
> thus no rule in bpf_convert_ctx_accesses() can recover it. Fix it by
> normalizing the merged type instead.
>
> Reuse it in is_load_acq_unsafe() to avoid open coding, and trim the
> overly verbose comment which is more of an implementation detail of
> bpf_convert_ctx_accesses() anyway.
>
> Fixes: f2362a57aeff ("bpf: allow void* cast using bpf_rdonly_cast()")
> Signed-off-by: Daniel Borkmann <[email protected]>
> ---
Acked-by: Eduard Zingerman <[email protected]>
...