emit_tst_imm() emits TEST (0xF7 /0) but sized the immediate with
imm_size(), which can return 1 byte. TEST has no imm8 form; it always
takes imm32. A small mask like BPF_JSET | BPF_K #0x1 then produced a
4-byte instruction the CPU decodes as 7, swallowing the following Jcc
and crashing.

Always emit a 32-bit immediate for TEST.

Bugzilla ID: 1959
Fixes: cc752e43e079 ("bpf: add JIT compilation for x86_64 ISA")
Cc: [email protected]

Signed-off-by: Stephen Hemminger <[email protected]>
---
 lib/bpf/bpf_jit_x86.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/bpf/bpf_jit_x86.c b/lib/bpf/bpf_jit_x86.c
index 88b1b5aeab..0ffe3783ff 100644
--- a/lib/bpf/bpf_jit_x86.c
+++ b/lib/bpf/bpf_jit_x86.c
@@ -921,7 +921,7 @@ emit_tst_imm(struct bpf_jit_state *st, uint32_t op, 
uint32_t dreg, uint32_t imm)
        emit_rex(st, op, 0, dreg);
        emit_bytes(st, &ops, sizeof(ops));
        emit_modregrm(st, MOD_DIRECT, mods, dreg);
-       emit_imm(st, imm, imm_size(imm));
+       emit_imm(st, imm, sizeof(int32_t));
 }
 
 static void
-- 
2.53.0

Reply via email to