timed may_goto passes a stack offset to the architecture trampoline,
which reconstructs the counter pointer from its BPF frame pointer. This
breaks when the JIT uses a private stack with a different frame pointer.
Resolve the counter pointer in the fixup using BPF_REG_FP and pass the
pointer through BPF_REG_AX. Account for the extra instruction in the
internal branch offsets.
Fixes: e723608bf428 ("bpf: Add verifier support for timed may_goto")
Reported-by: Jeremy Jean <[email protected]>
Link:
https://lore.kernel.org/all/[email protected]/
Signed-off-by: Siddharth Chintamaneni <[email protected]>
---
kernel/bpf/fixups.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/kernel/bpf/fixups.c b/kernel/bpf/fixups.c
index 65b441e4a351..dc59501a32bb 100644
--- a/kernel/bpf/fixups.c
+++ b/kernel/bpf/fixups.c
@@ -1797,20 +1797,20 @@ int bpf_do_misc_fixups(struct bpf_verifier_env *env)
stack_depth_extra = 16;
insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_AX,
BPF_REG_10, stack_off_cnt);
if (insn->off >= 0)
- insn_buf[1] = BPF_JMP_IMM(BPF_JEQ, BPF_REG_AX,
0, insn->off + 5);
+ insn_buf[1] = BPF_JMP_IMM(BPF_JEQ, BPF_REG_AX,
0, insn->off + 6);
else
insn_buf[1] = BPF_JMP_IMM(BPF_JEQ, BPF_REG_AX,
0, insn->off - 1);
insn_buf[2] = BPF_ALU64_IMM(BPF_SUB, BPF_REG_AX, 1);
- insn_buf[3] = BPF_JMP_IMM(BPF_JNE, BPF_REG_AX, 0, 2);
+ insn_buf[3] = BPF_JMP_IMM(BPF_JNE, BPF_REG_AX, 0, 3);
/*
- * AX is used as an argument to pass in stack_off_cnt
- * (to add to r10/fp), and also as the return value of
- * the call to arch_bpf_timed_may_goto.
+ * AX is used to pass FP + stack_off_cnt as the
argument to
+ * arch_bpf_timed_may_goto(), and also holds its return
value.
*/
- insn_buf[4] = BPF_MOV64_IMM(BPF_REG_AX, stack_off_cnt);
- insn_buf[5] = BPF_EMIT_CALL(arch_bpf_timed_may_goto);
- insn_buf[6] = BPF_STX_MEM(BPF_DW, BPF_REG_10,
BPF_REG_AX, stack_off_cnt);
- cnt = 7;
+ insn_buf[4] = BPF_MOV64_REG(BPF_REG_AX, BPF_REG_FP);
+ insn_buf[5] = BPF_ALU64_IMM(BPF_ADD, BPF_REG_AX,
stack_off_cnt);
+ insn_buf[6] = BPF_EMIT_CALL(arch_bpf_timed_may_goto);
+ insn_buf[7] = BPF_STX_MEM(BPF_DW, BPF_REG_10,
BPF_REG_AX, stack_off_cnt);
+ cnt = 8;
new_prog = bpf_patch_insn_data(env, i + delta,
insn_buf, cnt);
if (!new_prog)
@@ -2661,4 +2661,3 @@ int bpf_remove_fastcall_spills_fills(struct
bpf_verifier_env *env)
return 0;
}
-
--
2.43.0