Skip to content

Commit 6003cc5

Browse files
borkmanngregkh
authored andcommitted
bpf, arm64: fix jit branch offset related to ldimm64
[ Upstream commit ddc665a ] When the instruction right before the branch destination is a 64 bit load immediate, we currently calculate the wrong jump offset in the ctx->offset[] array as we only account one instruction slot for the 64 bit load immediate although it uses two BPF instructions. Fix it up by setting the offset into the right slot after we incremented the index. Before (ldimm64 test 1): [...] 00000020: 52800007 mov w7, #0x0 // #0 00000024: d2800060 mov x0, #0x3 // raspberrypi#3 00000028: d2800041 mov x1, #0x2 // raspberrypi#2 0000002c: eb01001f cmp x0, x1 00000030: 54ffff82 b.cs 0x00000020 00000034: d29fffe7 mov x7, #0xffff // #65535 00000038: f2bfffe7 movk x7, #0xffff, lsl raspberrypi#16 0000003c: f2dfffe7 movk x7, #0xffff, lsl raspberrypi#32 00000040: f2ffffe7 movk x7, #0xffff, lsl raspberrypi#48 00000044: d29dddc7 mov x7, #0xeeee // #61166 00000048: f2bdddc7 movk x7, #0xeeee, lsl raspberrypi#16 0000004c: f2ddddc7 movk x7, #0xeeee, lsl raspberrypi#32 00000050: f2fdddc7 movk x7, #0xeeee, lsl raspberrypi#48 [...] After (ldimm64 test 1): [...] 00000020: 52800007 mov w7, #0x0 // #0 00000024: d2800060 mov x0, #0x3 // raspberrypi#3 00000028: d2800041 mov x1, #0x2 // raspberrypi#2 0000002c: eb01001f cmp x0, x1 00000030: 540000a2 b.cs 0x00000044 00000034: d29fffe7 mov x7, #0xffff // #65535 00000038: f2bfffe7 movk x7, #0xffff, lsl raspberrypi#16 0000003c: f2dfffe7 movk x7, #0xffff, lsl raspberrypi#32 00000040: f2ffffe7 movk x7, #0xffff, lsl raspberrypi#48 00000044: d29dddc7 mov x7, #0xeeee // #61166 00000048: f2bdddc7 movk x7, #0xeeee, lsl raspberrypi#16 0000004c: f2ddddc7 movk x7, #0xeeee, lsl raspberrypi#32 00000050: f2fdddc7 movk x7, #0xeeee, lsl raspberrypi#48 [...] Also, add a couple of test cases to make sure JITs pass this test. Tested on Cavium ThunderX ARMv8. The added test cases all pass after the fix. Fixes: 8eee539 ("arm64: bpf: fix out-of-bounds read in bpf2a64_offset()") Reported-by: David S. Miller <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Acked-by: Alexei Starovoitov <[email protected]> Cc: Xi Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 9150b10 commit 6003cc5

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

arch/arm64/net/bpf_jit_comp.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -728,14 +728,14 @@ static int build_body(struct jit_ctx *ctx)
728728
int ret;
729729

730730
ret = build_insn(insn, ctx);
731-
732-
if (ctx->image == NULL)
733-
ctx->offset[i] = ctx->idx;
734-
735731
if (ret > 0) {
736732
i++;
733+
if (ctx->image == NULL)
734+
ctx->offset[i] = ctx->idx;
737735
continue;
738736
}
737+
if (ctx->image == NULL)
738+
ctx->offset[i] = ctx->idx;
739739
if (ret)
740740
return ret;
741741
}

lib/test_bpf.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4315,6 +4315,51 @@ static struct bpf_test tests[] = {
43154315
{ },
43164316
{ { 0, 1 } },
43174317
},
4318+
{
4319+
/* Mainly testing JIT + imm64 here. */
4320+
"JMP_JGE_X: ldimm64 test 1",
4321+
.u.insns_int = {
4322+
BPF_ALU32_IMM(BPF_MOV, R0, 0),
4323+
BPF_LD_IMM64(R1, 3),
4324+
BPF_LD_IMM64(R2, 2),
4325+
BPF_JMP_REG(BPF_JGE, R1, R2, 2),
4326+
BPF_LD_IMM64(R0, 0xffffffffffffffffUL),
4327+
BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeUL),
4328+
BPF_EXIT_INSN(),
4329+
},
4330+
INTERNAL,
4331+
{ },
4332+
{ { 0, 0xeeeeeeeeU } },
4333+
},
4334+
{
4335+
"JMP_JGE_X: ldimm64 test 2",
4336+
.u.insns_int = {
4337+
BPF_ALU32_IMM(BPF_MOV, R0, 0),
4338+
BPF_LD_IMM64(R1, 3),
4339+
BPF_LD_IMM64(R2, 2),
4340+
BPF_JMP_REG(BPF_JGE, R1, R2, 0),
4341+
BPF_LD_IMM64(R0, 0xffffffffffffffffUL),
4342+
BPF_EXIT_INSN(),
4343+
},
4344+
INTERNAL,
4345+
{ },
4346+
{ { 0, 0xffffffffU } },
4347+
},
4348+
{
4349+
"JMP_JGE_X: ldimm64 test 3",
4350+
.u.insns_int = {
4351+
BPF_ALU32_IMM(BPF_MOV, R0, 1),
4352+
BPF_LD_IMM64(R1, 3),
4353+
BPF_LD_IMM64(R2, 2),
4354+
BPF_JMP_REG(BPF_JGE, R1, R2, 4),
4355+
BPF_LD_IMM64(R0, 0xffffffffffffffffUL),
4356+
BPF_LD_IMM64(R0, 0xeeeeeeeeeeeeeeeeUL),
4357+
BPF_EXIT_INSN(),
4358+
},
4359+
INTERNAL,
4360+
{ },
4361+
{ { 0, 1 } },
4362+
},
43184363
/* BPF_JMP | BPF_JNE | BPF_X */
43194364
{
43204365
"JMP_JNE_X: if (3 != 2) return 1",

0 commit comments

Comments
 (0)