FAILED: patch "[PATCH] bpf, x86_32: Fix clobbering of dst for BPF_JSET" failed to apply to 4.19-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 4.19-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 50fe7ebb6475711c15b3397467e6424e20026d94 Mon Sep 17 00:00:00 2001
From: Luke Nelson <[email protected]>
Date: Wed, 22 Apr 2020 10:36:30 -0700
Subject: [PATCH] bpf, x86_32: Fix clobbering of dst for BPF_JSET
The current JIT clobbers the destination register for BPF_JSET BPF_X and BPF_K by using "and" and "or" instructions. This is fine when the destination register is a temporary loaded from a register stored on the stack but not otherwise.
This patch fixes the problem (for both BPF_K and BPF_X) by always loading the destination register into temporaries since BPF_JSET should not modify the destination register.
This bug may not be currently triggerable as BPF_REG_AX is the only register not stored on the stack and the verifier uses it in a limited way.
arch/x86/net/bpf_jit_comp32.c +18 -4
@@ -2015,8 +2015,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,case BPF_JMP |BPF_JSET |BPF_X :case BPF_JMP32 |BPF_JSET |BPF_X : {bool is_jmp64 =BPF_CLASS (insn->code) ==BPF_JMP ; -u8 dreg_lo = dstk ?IA32_EAX : dst_lo; -u8 dreg_hi = dstk ?IA32_EDX : dst_hi; +u8 dreg_lo =IA32_EAX ; +u8 dreg_hi =IA32_EDX ;u8 sreg_lo = sstk ?IA32_ECX : src_lo;u8 sreg_hi = sstk ?IA32_EBX : src_hi;
@@ -2028,6 +2028,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,add_2reg (0x40 ,IA32_EBP ,IA32_EDX ), STACK_VAR(dst_hi)); + }else { +/* mov dreg_lo,dst_lo */ +EMIT2 (0x89 ,add_2reg (0xC0 , dreg_lo, dst_lo)); +if (is_jmp64) +/* mov dreg_hi,dst_hi */ +EMIT2 (0x89 , +add_2reg (0xC0 , dreg_hi, dst_hi)); }if (sstk) {
@@ -2052,8 +2059,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,case BPF_JMP |BPF_JSET |BPF_K :case BPF_JMP32 |BPF_JSET |BPF_K : {bool is_jmp64 =BPF_CLASS (insn->code) ==BPF_JMP ; -u8 dreg_lo = dstk ?IA32_EAX : dst_lo; -u8 dreg_hi = dstk ?IA32_EDX : dst_hi; +u8 dreg_lo =IA32_EAX ; +u8 dreg_hi =IA32_EDX ;u8 sreg_lo =IA32_ECX ;u8 sreg_hi =IA32_EBX ;u32 hi;
@@ -2066,6 +2073,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,add_2reg (0x40 ,IA32_EBP ,IA32_EDX ), STACK_VAR(dst_hi)); + }else { +/* mov dreg_lo,dst_lo */ +EMIT2 (0x89 ,add_2reg (0xC0 , dreg_lo, dst_lo)); +if (is_jmp64) +/* mov dreg_hi,dst_hi */ +EMIT2 (0x89 , +add_2reg (0xC0 , dreg_hi, dst_hi)); }/* mov ecx,imm32 */