Re: [PATCH bpf-next v4 1/2] bpf: Fix sleepable check for tracing/lsm prog

[email protected]
Newsgroups org.kernel.vger.netdev,org.kernel.vger.bpf,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest
Message-ID <5a4179a9944f6e1e30be7a68a74d9c9f8c9c0eb986419fa2803ab99ce1362378@mail.kernel.org>
> 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?


---
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.