diff options
| author | Alexei Starovoitov <ast@kernel.org> | 2026-05-17 11:15:05 -0700 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2026-05-17 11:15:35 -0700 |
| commit | 201166d79fc01b607eccdddd4e1a7189f231904b (patch) | |
| tree | 685cace04b83584c2b352aea0d23ae05ae93100a /kernel/bpf/cfg.c | |
| parent | a828abbb897657451d96ad7bf20f1893ac983bb9 (diff) | |
| parent | 511a5db3c9ec55dd5393b8639000df080c296ef4 (diff) | |
Merge branch 'fix-bpf_throw-global-subprogs-interaction'
Kumar Kartikeya Dwivedi says:
====================
Fix bpf_throw() vs global subprogs interaction
There is a bug where bpf_throw()'s reachability across global subprogs
is missed by the verifier, leading to successful verification when any
kernel resource or lock is held across global subprog call boundary.
Fix this by effect summarization like other related side effects and
propagate exception reachability into callees.
Changelog:
----------
v1 -> v2
v1: https://lore.kernel.org/bpf/20260516022426.2109698-1-memxor@gmail.com
* Reorder might_throw bit to avoid bpf-next conflicts. (Alexei)
====================
Link: https://patch.msgid.link/20260517075530.3461166-1-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'kernel/bpf/cfg.c')
| -rw-r--r-- | kernel/bpf/cfg.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/kernel/bpf/cfg.c b/kernel/bpf/cfg.c index 998f42a8189a..26d37066465f 100644 --- a/kernel/bpf/cfg.c +++ b/kernel/bpf/cfg.c @@ -64,11 +64,19 @@ static void mark_subprog_might_sleep(struct bpf_verifier_env *env, int off) subprog->might_sleep = true; } +static void mark_subprog_might_throw(struct bpf_verifier_env *env, int off) +{ + struct bpf_subprog_info *subprog; + + subprog = bpf_find_containing_subprog(env, off); + subprog->might_throw = true; +} + /* 't' is an index of a call-site. * 'w' is a callee entry point. * Eventually this function would be called when env->cfg.insn_state[w] == EXPLORED. * Rely on DFS traversal order and absence of recursive calls to guarantee that - * callee's change_pkt_data marks would be correct at that moment. + * callee's effect marks would be correct at that moment. */ static void merge_callee_effects(struct bpf_verifier_env *env, int t, int w) { @@ -78,6 +86,7 @@ static void merge_callee_effects(struct bpf_verifier_env *env, int t, int w) callee = bpf_find_containing_subprog(env, w); caller->changes_pkt_data |= callee->changes_pkt_data; caller->might_sleep |= callee->might_sleep; + caller->might_throw |= callee->might_throw; } enum { @@ -509,6 +518,8 @@ static int visit_insn(int t, struct bpf_verifier_env *env) mark_subprog_might_sleep(env, t); if (ret == 0 && bpf_is_kfunc_pkt_changing(&meta)) mark_subprog_changes_pkt_data(env, t); + if (ret == 0 && bpf_is_throw_kfunc(insn)) + mark_subprog_might_throw(env, t); } return visit_func_call_insn(t, insns, env, insn->src_reg == BPF_PSEUDO_CALL); |
