Re: [PATCH bpf-next v3 8/9] riscv, bpf: Adjust bpf_func to account for CFI offset in bpf_jit_free
Pu Lehui <[email protected]>
| Newsgroups | dev.linux.lists.sashiko-reviews,org.kernel.vger.bpf |
|---|---|
| Message-ID | <[email protected]> |
On 2026/7/25 23:57, [email protected] wrote: > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: > > Pre-existing issues: > - [High] bpf_jit_free() ignores the error return value of bpf_jit_binary_pack_finalize(), leading to a Use-After-Free and Double Free of the JIT ro_header. > -- > > --- Patch [8]: [PATCH bpf-next v3 8/9] riscv, bpf: Adjust bpf_func to account for CFI offset in bpf_jit_free --- > commit a0a806deebfc4afdceb1a23fa093826ade44c8cf > Author: Pu Lehui <[email protected]> > > riscv, bpf: Adjust bpf_func to account for CFI offset in bpf_jit_free > > When CFI is enabled, the actual BPF program entry point is shifted forward > by a CFI preamble. This commit subtracts the CFI offset from prog->bpf_func > in bpf_jit_free() to restore the original JITed allocation address before > freeing it, preventing an invalid memory free. > >> diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c >> index cbfcd287ea166..059db1adeaf8d 100644 >> --- a/arch/riscv/net/bpf_jit_core.c >> +++ b/arch/riscv/net/bpf_jit_core.c >> @@ -237,6 +237,7 @@ void bpf_jit_free(struct bpf_prog *prog) >> kvfree(jit_data->ctx.offset); >> kfree(jit_data); >> } >> + prog->bpf_func = (void *)prog->bpf_func - cfi_get_offset(); >> hdr = bpf_jit_binary_pack_hdr(prog); >> bpf_jit_binary_pack_free(hdr, NULL); > > [Severity: High] > This is a pre-existing issue, but does ignoring the return value of > bpf_jit_binary_pack_finalize() (called just prior to this diff snippet) > lead to a use-after-free and double free? patch 9 has been covered this. > > If bpf_jit_binary_pack_finalize() fails, it frees ro_header internally: > > kernel/bpf/core.c:bpf_jit_binary_pack_finalize() { > ... > if (IS_ERR(ptr)) { > bpf_prog_pack_free(ro_header, ro_header->size); > return PTR_ERR(ptr); > } > ... > } > > Back in bpf_jit_free(), we ignore this failure, extract the same freed > header via bpf_jit_binary_pack_hdr(), and call bpf_jit_binary_pack_free() > which dereferences ro_header->size and frees it again: > > kernel/bpf/core.c:bpf_jit_binary_pack_free() { > u32 size = ro_header->size; > > bpf_prog_pack_free(ro_header, size); > ... > } > > Should bpf_jit_free() check if bpf_jit_binary_pack_finalize() returned > an error before attempting to extract and free the header again? > >> WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(prog)); >