bpf: handle jset (if a & b ...) as a jump in CFG computation
Subsystems (4)
Eduard Zingerman
maintainerPATCH 1/2 bpf: handle jset (if a & b ...) as a jump in CFG computation
BPF_JSET is a conditional jump and currently verifier.c:can_jump() does not know about that. This can lead to incorrect live registers and SCC computation.
E.g. in the following example:
1: r0 = 1; 2: r2 = 2; 3: if r1 & 0x7 goto +1; 4: exit; 5: r0 = r2; 6: exit;
W/o this fix insn_successors(3) will return only (4), a jump to (5) would be missed and r2 won't be marked as alive at (3).
--- kernel/bpf/verifier.c | 1 + 1 file changed, 1 insertion(+)
kernel/bpf/verifier.c +1 -0
@@ -23950,6 +23950,7 @@ static bool can_jump(struct bpf_insn *insn)case BPF_JSLT :case BPF_JSLE :case BPF_JCOND : +case BPF_JSET :return true; }
Signature · 1 line
2.47.1
Eduard Zingerman
maintainerPATCH 2/2 selftests/bpf: verify jset handling in CFG computation
A test case to check if both branches of jset are explored when computing program CFG.
At 'if r1 & 0x7 ...':
- register 'r2' is computed alive only if jump branch of jset instruction is followed;
- register 'r0' is computed alive only if fallthrough branch of jset instruction is followed.
--- .../selftests/bpf/progs/compute_live_registers.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
tools/testing/selftests/bpf/progs/compute_live_registers.c +16 -0
@@ -240,6 +240,22 @@ __naked void if2(void) ::: __clobber_all); } +/* Verifier misses that r2 is alive if jset is not handled properly */ +SEC("socket") +__log_level(2) +__msg("2: 012....... (45) if r1 & 0x7 goto pc+1") +__naked void if3_jset_bug (void ) +{ + asmvolatile ( +"r0 = 1;" +"r2 = 2;" +"if r1 & 0x7 goto +1;" +"exit;" +"r0 = r2;" +"exit;" + ::: __clobber_all); +} + SEC("socket") __log_level(2)__msg ("0: .......... (b7) r1 = 0" )
Signature · 1 line
2.47.1
This series was applied to bpf/bpf-next.git (master) by Alexei Starovoitov <[email protected]>:
Hello:
This series was applied to bpf/bpf-next.git (master) by Alexei Starovoitov <[email protected]>:
Quoted 6 lines · On Fri, 13 Jun 2025 10:53:30 -0700 you wrote:
BPF_JSETis a conditional jump and currently verifier.c:can_jump() does not know about that. This can lead to incorrect live registers and SCC computation.E.g. in the following example:
Quoted 8 lines
1: r0 = 1; 2: r2 = 2; 3: if r1 & 0x7 goto +1; 4: exit; 5: r0 = r2; 6: exit;[...]
Here is the summary with links:
- [bpf-next,v1,1/2] bpf: handle jset (if a & b ...) as a jump in CFG computation
https://git.kernel.org/bpf/bpf-next/c/3157f7e29996 - [bpf-next,v1,2/2] selftests/bpf: verify jset handling in CFG computation https://git.kernel.org/bpf/bpf-next/c/4a4b84ba9e45
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html