From: Greg Kroah-Hartman Date: Mon, 19 Mar 2018 17:12:58 +0000 (+0100) Subject: 4.4-stable patches X-Git-Tag: v4.15.12~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fd1fabb1e22dac6bffb28a89801092a64fed0a80;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: bpf-fix-incorrect-sign-extension-in-check_alu_op.patch --- diff --git a/queue-4.4/bpf-fix-incorrect-sign-extension-in-check_alu_op.patch b/queue-4.4/bpf-fix-incorrect-sign-extension-in-check_alu_op.patch new file mode 100644 index 00000000000..7958411f9be --- /dev/null +++ b/queue-4.4/bpf-fix-incorrect-sign-extension-in-check_alu_op.patch @@ -0,0 +1,99 @@ +From jannh@google.com Mon Mar 19 18:11:54 2018 +From: Jann Horn +Date: Mon, 19 Mar 2018 17:55:52 +0100 +Subject: bpf: fix incorrect sign extension in check_alu_op() +To: stable@vger.kernel.org +Cc: security@kernel.org, "David S. Miller" , Daniel Borkmann , Alexei Starovoitov , Greg Kroah-Hartman +Message-ID: <20180319165552.146891-1-jannh@google.com> + +From: Jann Horn + +commit 95a762e2c8c942780948091f8f2a4f32fce1ac6f upstream. + +Distinguish between +BPF_ALU64|BPF_MOV|BPF_K (load 32-bit immediate, sign-extended to 64-bit) +and BPF_ALU|BPF_MOV|BPF_K (load 32-bit immediate, zero-padded to 64-bit); +only perform sign extension in the first case. + +This patch differs from the mainline one because the verifier's internals +have changed in the meantime. Mainline tracks register values as 64-bit +values; however, 4.4 still stores tracked register values as 32-bit +values with sign extension. Therefore, in the case of a 32-bit op with +negative immediate, the value can't be tracked; leave the register as +UNKNOWN_VALUE (set by the preceding check_reg_arg() call). + + +I have manually tested this patch on top of 4.4.122. For the following BPF +bytecode: + + BPF_MOV64_IMM(BPF_REG_1, 1), + BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1), + BPF_EXIT_INSN(), + + BPF_MOV32_IMM(BPF_REG_1, 1), + BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 1, 1), + BPF_EXIT_INSN(), + + BPF_MOV64_IMM(BPF_REG_1, -1), + BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, -1, 1), + BPF_EXIT_INSN(), + + BPF_MOV32_IMM(BPF_REG_1, -1), + BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, -1, 2), + BPF_MOV32_IMM(BPF_REG_0, 42), + BPF_EXIT_INSN(), + + BPF_MOV32_IMM(BPF_REG_0, 43), + BPF_EXIT_INSN() + +Verifier output on 4.4.122 without this patch: + +0: (b7) r1 = 1 +1: (15) if r1 == 0x1 goto pc+1 +3: (b4) (u32) r1 = (u32) 1 +4: (15) if r1 == 0x1 goto pc+1 +6: (b7) r1 = -1 +7: (15) if r1 == 0xffffffff goto pc+1 +9: (b4) (u32) r1 = (u32) -1 +10: (15) if r1 == 0xffffffff goto pc+2 +13: (b4) (u32) r0 = (u32) 43 +14: (95) exit + +Verifier output on 4.4.122+ with this patch: + +0: (b7) r1 = 1 +1: (15) if r1 == 0x1 goto pc+1 +3: (b4) (u32) r1 = (u32) 1 +4: (15) if r1 == 0x1 goto pc+1 +6: (b7) r1 = -1 +7: (15) if r1 == 0xffffffff goto pc+1 +9: (b4) (u32) r1 = (u32) -1 +10: (15) if r1 == 0xffffffff goto pc+2 + R1=inv R10=fp +11: (b4) (u32) r0 = (u32) 42 +12: (95) exit + +from 10 to 13: R1=imm-1 R10=fp +13: (b4) (u32) r0 = (u32) 43 +14: (95) exit + + +Signed-off-by: Jann Horn +Acked-by: Daniel Borkmann +Signed-off-by: Greg Kroah-Hartman +--- + kernel/bpf/verifier.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -1135,7 +1135,8 @@ static int check_alu_op(struct verifier_ + regs[insn->dst_reg].type = UNKNOWN_VALUE; + regs[insn->dst_reg].map_ptr = NULL; + } +- } else { ++ } else if (BPF_CLASS(insn->code) == BPF_ALU64 || ++ insn->imm >= 0) { + /* case: R = imm + * remember the value we stored into this reg + */ diff --git a/queue-4.4/series b/queue-4.4/series index 49fb14838c8..21346e38d6d 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -131,3 +131,4 @@ btrfs-alloc_chunk-fix-dup-stripe-size-handling.patch btrfs-fix-use-after-free-when-cleaning-up-fs_devs-with-a-single-stale-device.patch usb-gadget-udc-add-missing-platform_device_put-on-error-in-bdc_pci_probe.patch usb-gadget-bdc-64-bit-pointer-capability-check.patch +bpf-fix-incorrect-sign-extension-in-check_alu_op.patch