From: Daniel Borkmann <daniel@iogearbox.net>
To: ast@kernel.org
Cc: memxor@gmail.com, eddyz87@gmail.com, a.s.protopopov@gmail.com,
info@starlabs.sg, bpf@vger.kernel.org
Subject: [PATCH bpf 2/6] bpf: Bound the number of indirect jump edges in a program
Date: Wed, 9 Sep 2026 22:40:31 +0200 [thread overview]
Message-ID: <20260909204035.24289-2-daniel@iogearbox.net> (raw)
In-Reply-To: <20260909204035.24289-1-daniel@iogearbox.net>
Every gotox instruction gets its own copy of the jump table of the subprog
containing it, and each distinct target in that table is a CFG successor
of the instruction. The number of such edges is therefore the number of
gotox instructions times the number of distinct targets, and neither
factor is bounded by anything except the instruction limit.
What is expensive is a BPF prog whose gotox instructions are themselves
the targets, which makes the edge count quadratic. 1024 such gotox are
already ~1e6 edges and about 4s of CPU to load.
Bound the total across the program at BPF_COMPLEXITY_LIMIT_INSNS, aka
the limit as the number of instructions the verifier processes. Progs
with real switch statements are orders of magnitude below this.
Fixes: 493d9e0d6083 ("bpf, x86: add support for indirect jumps")
Reported-by: STAR Labs SG <info@starlabs.sg>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
---
include/linux/bpf_verifier.h | 1 +
kernel/bpf/cfg.c | 15 +++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 36b65797877d..04bb8f71cabe 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -977,6 +977,7 @@ struct bpf_verifier_env {
int cur_stack;
/* current position in the insn_postorder vector */
int cur_postorder;
+ u32 gotox_edges;
} cfg;
struct backtrack_state bt;
struct bpf_jmp_history_entry *cur_hist_ent;
diff --git a/kernel/bpf/cfg.c b/kernel/bpf/cfg.c
index 081f7003eae6..e9910228da58 100644
--- a/kernel/bpf/cfg.c
+++ b/kernel/bpf/cfg.c
@@ -9,6 +9,8 @@
#define verbose(env, fmt, args...) bpf_verifier_log_write(env, fmt, ##args)
+#define BPF_MAX_GOTOX_EDGES BPF_COMPLEXITY_LIMIT_INSNS
+
/* non-recursive DFS pseudo code
* 1 procedure DFS-iterative(G,v):
* 2 label v as discovered
@@ -388,6 +390,19 @@ static int visit_gotox_insn(int t, struct bpf_verifier_env *env)
return PTR_ERR(jt);
env->insn_aux_data[t].jt = jt;
+
+ if (check_add_overflow(env->cfg.gotox_edges, jt->cnt,
+ &env->cfg.gotox_edges) ||
+ env->cfg.gotox_edges > BPF_MAX_GOTOX_EDGES) {
+ verbose(env, "number of indirect jump edges in the program exceeds %u\n",
+ BPF_MAX_GOTOX_EDGES);
+ bpf_diag_program_structure(
+ env, t, "too many indirect jump edges",
+ "Reduce the number of indirect jumps, or the number of distinct targets they can reach.",
+ "The program has more than %u indirect jump edges in total, counted over every gotox instruction.",
+ BPF_MAX_GOTOX_EDGES);
+ return -E2BIG;
+ }
}
mark_prune_point(env, t);
--
2.43.0
next prev parent reply other threads:[~2026-09-09 20:40 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-09 20:40 [PATCH bpf 1/6] bpf: Avoid quadratic successor rescan in bpf_compute_scc Daniel Borkmann
2026-09-09 20:40 ` Daniel Borkmann [this message]
2026-09-09 20:57 ` [PATCH bpf 2/6] bpf: Bound the number of indirect jump edges in a program sashiko-bot
2026-09-10 11:15 ` Daniel Borkmann
2026-09-10 11:44 ` Anton Protopopov
2026-09-09 20:40 ` [PATCH bpf 3/6] bpf: Cache the jump table of a subprogram during CFG discovery Daniel Borkmann
2026-09-09 21:34 ` bot+bpf-ci
2026-09-10 11:21 ` Daniel Borkmann
2026-09-10 11:46 ` Anton Protopopov
2026-09-10 21:02 ` Eduard Zingerman
2026-09-09 20:40 ` [PATCH bpf 4/6] bpf: Reject indirect jumps that leave their subprogram Daniel Borkmann
2026-09-09 21:50 ` bot+bpf-ci
2026-09-10 12:10 ` Anton Protopopov
2026-09-10 19:37 ` Eduard Zingerman
2026-09-09 20:40 ` [PATCH bpf 5/6] selftests/bpf: Add tests for the indirect jump edge limit Daniel Borkmann
2026-09-09 21:34 ` bot+bpf-ci
2026-09-10 12:14 ` Anton Protopopov
2026-09-09 20:40 ` [PATCH bpf 6/6] selftests/bpf: Add tests for indirect jumps across subprograms Daniel Borkmann
2026-09-09 21:34 ` bot+bpf-ci
2026-09-10 12:22 ` Anton Protopopov
2026-09-10 18:54 ` [PATCH bpf 1/6] bpf: Avoid quadratic successor rescan in bpf_compute_scc Eduard Zingerman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260909204035.24289-2-daniel@iogearbox.net \
--to=daniel@iogearbox.net \
--cc=a.s.protopopov@gmail.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=eddyz87@gmail.com \
--cc=info@starlabs.sg \
--cc=memxor@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox