Skip to content

Commit 2d2b87f

Browse files
laoarKernel Patches Daemon
authored and
Kernel Patches Daemon
committed
bpf: Reject attaching fexit to functions annotated with __noreturn
If we attach fexit to a function annotated with __noreturn, it will cause an issue that the bpf trampoline image will be left over even if the bpf link has been destroyed. Take attaching do_exit() for example. The fexit works as follows, bpf_trampoline + __bpf_tramp_enter + percpu_ref_get(&tr->pcref); + call do_exit() + __bpf_tramp_exit + percpu_ref_put(&tr->pcref); Since do_exit() never returns, the refcnt of the trampoline image is never decremented, preventing it from being freed. This can be verified with as follows, $ bpftool link show <<<< nothing output $ grep "bpf_trampoline_[0-9]" /proc/kallsyms ffffffffc04cb000 t bpf_trampoline_6442526459 [bpf] <<<< leftover With this change, attaching fexit probes to functions like do_exit() will be rejected. $ ./fexit libbpf: prog 'fexit': BPF program load failed: -EINVAL libbpf: prog 'fexit': -- BEGIN PROG LOAD LOG -- processed 0 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0 -- END PROG LOAD LOG -- libbpf: prog 'fexit': failed to load: -EINVAL libbpf: failed to load object 'fexit_bpf' libbpf: failed to load BPF skeleton 'fexit_bpf': -EINVAL failed to load BPF object -22 Signed-off-by: Yafang Shao <[email protected]>
1 parent 77edccc commit 2d2b87f

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

kernel/bpf/verifier.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22841,6 +22841,13 @@ BTF_ID(func, __rcu_read_unlock)
2284122841
#endif
2284222842
BTF_SET_END(btf_id_deny)
2284322843

22844+
/* The functions annotated with __noreturn are denied. */
22845+
BTF_SET_START(fexit_deny)
22846+
#define NORETURN(fn) BTF_ID(func, fn)
22847+
#include <linux/noreturns.h>
22848+
#undef NORETURN
22849+
BTF_SET_END(fexit_deny)
22850+
2284422851
static bool can_be_sleepable(struct bpf_prog *prog)
2284522852
{
2284622853
if (prog->type == BPF_PROG_TYPE_TRACING) {
@@ -22929,6 +22936,9 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
2292922936
} else if (prog->type == BPF_PROG_TYPE_TRACING &&
2293022937
btf_id_set_contains(&btf_id_deny, btf_id)) {
2293122938
return -EINVAL;
22939+
} else if (prog->expected_attach_type == BPF_TRACE_FEXIT &&
22940+
btf_id_set_contains(&fexit_deny, btf_id)) {
22941+
return -EINVAL;
2293222942
}
2293322943

2293422944
key = bpf_trampoline_compute_key(tgt_prog, prog->aux->attach_btf, btf_id);

0 commit comments

Comments
 (0)