On Wed, Aug 5, 2026 at 9:44 AM <[email protected]> wrote:
>
> > Similar issue could be applied to lsm prog, when the
> > prog->aux->attach_btf_id is in the LSM allowing list but the attach_btf is
> > a malicious bpf prog's btf.
>
> Can this LSM scenario actually occur? Looking at the code,
> prog->aux->attach_btf appears to be validated to be kernel BTF at program
> load time in bpf_prog_load():
>
> kernel/bpf/syscall.c:2991
>         attach_btf = btf_get_by_fd(attr->attach_btf_obj_fd);
>         ...
>         if (!btf_is_kernel(attach_btf)) {
>                 /* attaching through specifying bpf_prog's BTF
>                  * objects directly might be supported eventually
>                  */
>                 btf_put(attach_btf);
>                 err = -ENOTSUPP;
>
> The only other assignment is the bpf_get_btf_vmlinux() fallback at
> syscall.c:3007, so attach_btf is never a bpf prog's BTF.
>
> The other path for non-kernel BTF reaching btf_id_allow_sleepable() is
> the tgt_prog branch in bpf_check_attach_target():
>
> kernel/bpf/verifier.c:19149
>         btf = tgt_prog ? tgt_prog->aux->btf : prog->aux->attach_btf;
>
> But can an LSM program have a tgt_prog? bpf_prog_load_check_attach()
> appears to reject it at load:
>
> kernel/bpf/syscall.c:2752
>         if (dst_prog && prog_type != BPF_PROG_TYPE_TRACING &&
>             prog_type != BPF_PROG_TYPE_EXT)
>                 return -EINVAL;
>
> And bpf_tracing_prog_attach() only accepts tgt_prog_fd for BPF_PROG_TYPE_EXT
> (syscall.c:3673). So the BPF_PROG_TYPE_LSM arm of btf_id_allow_sleepable()
> appears to be only ever reached with kernel BTF, making the 'malicious bpf
> prog's btf' case unreachable.
>
> > Fix it by disallowing sleepable tracing/lsm prog always when its target
> > btf is not kernel's btf.
> >
> > Fixes: 16d9c5660692 ("bpf: Always allow sleepable programs on syscalls")
> > Fixes: 1e6c62a88215 ("bpf: Introduce sleepable BPF programs")
>
> Does the second Fixes: tag point at the commit that introduced the bug?
> Looking at 1e6c62a88215 and up through 16d9c5660692, the tracing arm read:
>
>         if (!check_non_sleepable_error_inject(btf_id) &&
>             within_error_injection_list(addr))
>
> On the tgt_prog path, addr is JIT text (tgt_prog->bpf_func /
> aux->func[subprog]->bpf_func, verifier.c:19409-19412), which is never on
> the error-injection list. With CONFIG_FUNCTION_ERROR_INJECTION=n,
> within_error_injection_list() is a stub returning false
> (include/linux/error-injection.h:16).
>
> The fmodret fallback also does not help, because
> btf_kfunc_is_modify_return() checks __btf_kfunc_is_allowed(), which returns
> false when btf->kfunc_set_tab is NULL (kernel/bpf/btf.c:9021), and
> kfunc_set_tab is only populated for vmlinux/module BTF
> (__register_btf_kfunc_id_set() calls btf_get_module_btf(), btf.c:9160).
>
> So a sleepable tracing prog attaching to another BPF program was already
> rejected before 16d9c5660692. Only the has_arch_syscall_prefix(tname) path
> added by 16d9c5660692 opened the hole. Keeping the 1e6c62a88215 tag could
> direct AUTOSEL and stable at trees back to 5.10 that do not contain the
> bug.
>
> Would Fixes: 16d9c5660692 alone be more accurate?

Yes, I dropped second Fixes and reworded patch #1 and cover letter a
tiny bit. pushed to bpf-next

>
>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
>
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/31020655174

Reply via email to