From: Greg Kroah-Hartman Date: Mon, 8 Oct 2018 13:27:39 +0000 (+0200) Subject: 4.18-stable patches X-Git-Tag: v4.4.160~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9307a020e6c1555f9f7ebce8763b63c3505b71cb;p=thirdparty%2Fkernel%2Fstable-queue.git 4.18-stable patches added patches: bpf-32-bit-rsh-verification-must-truncate-input-before-the-alu-op.patch --- diff --git a/queue-4.18/bpf-32-bit-rsh-verification-must-truncate-input-before-the-alu-op.patch b/queue-4.18/bpf-32-bit-rsh-verification-must-truncate-input-before-the-alu-op.patch new file mode 100644 index 00000000000..f132f9f64c2 --- /dev/null +++ b/queue-4.18/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 +@@ -2865,6 +2865,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; +@@ -3100,7 +3109,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.18/series b/queue-4.18/series index 1f07150ec6e..99a3032c840 100644 --- a/queue-4.18/series +++ b/queue-4.18/series @@ -75,3 +75,4 @@ ceph-avoid-a-use-after-free-in-ceph_destroy_options.patch firmware-arm_scmi-fix-divide-by-zero-when-sustained_perf_level-is-zero.patch afs-fix-cell-specification-to-permit-an-empty-address-list.patch mm-madvise-madv_dodump-allow-hugetlbfs-pages.patch +bpf-32-bit-rsh-verification-must-truncate-input-before-the-alu-op.patch