]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/6.6.26/bpf-arm64-fix-bug-in-bpf_ldx_memsx.patch
Linux 6.6.26
[thirdparty/kernel/stable-queue.git] / releases / 6.6.26 / bpf-arm64-fix-bug-in-bpf_ldx_memsx.patch
1 From 870a8b4bdfdae6347ff7d76809506fdc23a8e9f7 Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Tue, 12 Mar 2024 23:59:17 +0000
4 Subject: bpf, arm64: fix bug in BPF_LDX_MEMSX
5
6 From: Puranjay Mohan <puranjay12@gmail.com>
7
8 [ Upstream commit 114b5b3b4bde7358624437be2f12cde1b265224e ]
9
10 A64_LDRSW() takes three registers: Xt, Xn, Xm as arguments and it loads
11 and sign extends the value at address Xn + Xm into register Xt.
12
13 Currently, the offset is being directly used in place of the tmp
14 register which has the offset already loaded by the last emitted
15 instruction.
16
17 This will cause JIT failures. The easiest way to reproduce this is to
18 test the following code through test_bpf module:
19
20 {
21 "BPF_LDX_MEMSX | BPF_W",
22 .u.insns_int = {
23 BPF_LD_IMM64(R1, 0x00000000deadbeefULL),
24 BPF_LD_IMM64(R2, 0xffffffffdeadbeefULL),
25 BPF_STX_MEM(BPF_DW, R10, R1, -7),
26 BPF_LDX_MEMSX(BPF_W, R0, R10, -7),
27 BPF_JMP_REG(BPF_JNE, R0, R2, 1),
28 BPF_ALU64_IMM(BPF_MOV, R0, 0),
29 BPF_EXIT_INSN(),
30 },
31 INTERNAL,
32 { },
33 { { 0, 0 } },
34 .stack_depth = 7,
35 },
36
37 We need to use the offset as -7 to trigger this code path, there could
38 be other valid ways to trigger this from proper BPF programs as well.
39
40 This code is rejected by the JIT because -7 is passed to A64_LDRSW() but
41 it expects a valid register (0 - 31).
42
43 roott@pjy:~# modprobe test_bpf test_name="BPF_LDX_MEMSX | BPF_W"
44 [11300.490371] test_bpf: test_bpf: set 'test_bpf' as the default test_suite.
45 [11300.491750] test_bpf: #345 BPF_LDX_MEMSX | BPF_W
46 [11300.493179] aarch64_insn_encode_register: unknown register encoding -7
47 [11300.494133] aarch64_insn_encode_register: unknown register encoding -7
48 [11300.495292] FAIL to select_runtime err=-524
49 [11300.496804] test_bpf: Summary: 0 PASSED, 1 FAILED, [0/0 JIT'ed]
50 modprobe: ERROR: could not insert 'test_bpf': Invalid argument
51
52 Applying this patch fixes the issue.
53
54 root@pjy:~# modprobe test_bpf test_name="BPF_LDX_MEMSX | BPF_W"
55 [ 292.837436] test_bpf: test_bpf: set 'test_bpf' as the default test_suite.
56 [ 292.839416] test_bpf: #345 BPF_LDX_MEMSX | BPF_W jited:1 156 PASS
57 [ 292.844794] test_bpf: Summary: 1 PASSED, 0 FAILED, [1/1 JIT'ed]
58
59 Fixes: cc88f540da52 ("bpf, arm64: Support sign-extension load instructions")
60 Signed-off-by: Puranjay Mohan <puranjay12@gmail.com>
61 Message-ID: <20240312235917.103626-1-puranjay12@gmail.com>
62 Signed-off-by: Alexei Starovoitov <ast@kernel.org>
63 Signed-off-by: Sasha Levin <sashal@kernel.org>
64 ---
65 arch/arm64/net/bpf_jit_comp.c | 2 +-
66 1 file changed, 1 insertion(+), 1 deletion(-)
67
68 diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
69 index 150d1c6543f7f..5fe4d8b3fdc89 100644
70 --- a/arch/arm64/net/bpf_jit_comp.c
71 +++ b/arch/arm64/net/bpf_jit_comp.c
72 @@ -1189,7 +1189,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
73 } else {
74 emit_a64_mov_i(1, tmp, off, ctx);
75 if (sign_extend)
76 - emit(A64_LDRSW(dst, src_adj, off_adj), ctx);
77 + emit(A64_LDRSW(dst, src, tmp), ctx);
78 else
79 emit(A64_LDR32(dst, src, tmp), ctx);
80 }
81 --
82 2.43.0
83