]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 8 Oct 2018 13:27:39 +0000 (15:27 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 8 Oct 2018 13:27:39 +0000 (15:27 +0200)
added patches:
bpf-32-bit-rsh-verification-must-truncate-input-before-the-alu-op.patch

queue-4.18/bpf-32-bit-rsh-verification-must-truncate-input-before-the-alu-op.patch [new file with mode: 0644]
queue-4.18/series

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 (file)
index 0000000..f132f9f
--- /dev/null
@@ -0,0 +1,59 @@
+From b799207e1e1816b09e7a5920fbb2d5fcf6edd681 Mon Sep 17 00:00:00 2001
+From: Jann Horn <jannh@google.com>
+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 <jannh@google.com>
+
+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 <daniel@iogearbox.net>
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
index 1f07150ec6ec62338ef2a4c720d2184ae5119799..99a3032c840d6d106b56c25063e9a3ad9858dd97 100644 (file)
@@ -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