From: Greg Kroah-Hartman Date: Mon, 8 Oct 2018 13:27:23 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v4.4.160~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2b761fcece188d964f874e34327d710f40dc187b;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: bpf-32-bit-rsh-verification-must-truncate-input-before-the-alu-op.patch --- diff --git a/queue-4.14/bpf-32-bit-rsh-verification-must-truncate-input-before-the-alu-op.patch b/queue-4.14/bpf-32-bit-rsh-verification-must-truncate-input-before-the-alu-op.patch new file mode 100644 index 00000000000..9e9da8ccde5 --- /dev/null +++ b/queue-4.14/bpf-32-bit-rsh-verification-must-truncate-input-before-the-alu-op.patch @@ -0,0 +1,59 @@ +From b799207e1e1816b09e7a5920fbb2d5fcf6edd681 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Fri, 5 Oct 2018 18:17:59 +0200 +Subject: bpf: 32-bit RSH verification must truncate input before the ALU op + +From: Jann Horn + +commit b799207e1e1816b09e7a5920fbb2d5fcf6edd681 upstream. + +When I wrote commit 468f6eafa6c4 ("bpf: fix 32-bit ALU op verification"), I +assumed that, in order to emulate 64-bit arithmetic with 32-bit logic, it +is sufficient to just truncate the output to 32 bits; and so I just moved +the register size coercion that used to be at the start of the function to +the end of the function. + +That assumption is true for almost every op, but not for 32-bit right +shifts, because those can propagate information towards the least +significant bit. Fix it by always truncating inputs for 32-bit ops to 32 +bits. + +Also get rid of the coerce_reg_to_size() after the ALU op, since that has +no effect. + +Fixes: 468f6eafa6c4 ("bpf: fix 32-bit ALU op verification") +Acked-by: Daniel Borkmann +Signed-off-by: Jann Horn +Signed-off-by: Daniel Borkmann +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/bpf/verifier.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -2076,6 +2076,15 @@ static int adjust_scalar_min_max_vals(st + u64 umin_val, umax_val; + u64 insn_bitness = (BPF_CLASS(insn->code) == BPF_ALU64) ? 64 : 32; + ++ if (insn_bitness == 32) { ++ /* Relevant for 32-bit RSH: Information can propagate towards ++ * LSB, so it isn't sufficient to only truncate the output to ++ * 32 bits. ++ */ ++ coerce_reg_to_size(dst_reg, 4); ++ coerce_reg_to_size(&src_reg, 4); ++ } ++ + smin_val = src_reg.smin_value; + smax_val = src_reg.smax_value; + umin_val = src_reg.umin_value; +@@ -2295,7 +2304,6 @@ static int adjust_scalar_min_max_vals(st + if (BPF_CLASS(insn->code) != BPF_ALU64) { + /* 32-bit ALU ops are (32,32)->32 */ + coerce_reg_to_size(dst_reg, 4); +- coerce_reg_to_size(&src_reg, 4); + } + + __reg_deduce_bounds(dst_reg); diff --git a/queue-4.14/series b/queue-4.14/series index 7b89d3ae01e..f022e01381b 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -38,3 +38,4 @@ mac80211-shorten-the-ibss-debug-messages.patch tools-vm-slabinfo.c-fix-sign-compare-warning.patch tools-vm-page-types.c-fix-defined-but-not-used-warning.patch mm-madvise-madv_dodump-allow-hugetlbfs-pages.patch +bpf-32-bit-rsh-verification-must-truncate-input-before-the-alu-op.patch