Skip to content

Commit 7fd3b41

Browse files
borkmanngregkh
authored andcommitted
bpf, arm64: Fix off-by-one in check_imm signed range check
[ Upstream commit 1dd8be4 ] check_imm(bits, imm) is used in the arm64 BPF JIT to verify that a branch displacement (in arm64 instruction units) fits into the signed N-bit immediate field of a B, B.cond or CBZ/CBNZ encoding before it is handed to the encoder. The macro currently tests for (imm > 0 && imm >> bits) || (imm < 0 && ~imm >> bits) which admits values in [-2^N, 2^N) — effectively a signed (N+1)-bit range. A signed N-bit field only holds [-2^(N-1), 2^(N-1)), so the check admits one extra bit of range on each side. In particular, for check_imm19(), values in [2^18, 2^19) slip past the check but do not fit into the 19-bit signed imm19 field of B.cond. aarch64_insn_encode_immediate() then masks the raw value into the 19-bit field, setting bit 18 (the sign bit) and flipping a forward branch into a backward one. Same class of issue exists for check_imm26() and the B/BL encoding. Shift by (bits - 1) instead of bits so the actual signed N-bit range is enforced. Fixes: e54bcde ("arm64: eBPF JIT compiler") Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: Puranjay Mohan <puranjay@kernel.org> Link: https://lore.kernel.org/r/20260415121403.639619-2-daniel@iogearbox.net Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent ad4505d commit 7fd3b41

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

arch/arm64/net/bpf_jit_comp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
#define FP_BOTTOM (MAX_BPF_JIT_REG + 4)
3434

3535
#define check_imm(bits, imm) do { \
36-
if ((((imm) > 0) && ((imm) >> (bits))) || \
37-
(((imm) < 0) && (~(imm) >> (bits)))) { \
36+
if ((((imm) > 0) && ((imm) >> ((bits) - 1))) || \
37+
(((imm) < 0) && (~(imm) >> ((bits) - 1)))) { \
3838
pr_info("[%2d] imm=%d(0x%x) out of range\n", \
3939
i, imm, imm); \
4040
return -EINVAL; \

0 commit comments

Comments
 (0)