]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 20 Mar 2021 10:41:50 +0000 (11:41 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 20 Mar 2021 10:41:50 +0000 (11:41 +0100)
added patches:
bpf-prohibit-alu-ops-for-pointer-types-not-defining-ptr_limit.patch

queue-4.14/bpf-prohibit-alu-ops-for-pointer-types-not-defining-ptr_limit.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/bpf-prohibit-alu-ops-for-pointer-types-not-defining-ptr_limit.patch b/queue-4.14/bpf-prohibit-alu-ops-for-pointer-types-not-defining-ptr_limit.patch
new file mode 100644 (file)
index 0000000..09fb2d0
--- /dev/null
@@ -0,0 +1,84 @@
+From f232326f6966cf2a1d1db7bc917a4ce5f9f55f76 Mon Sep 17 00:00:00 2001
+From: Piotr Krysiuk <piotras@gmail.com>
+Date: Tue, 16 Mar 2021 09:47:02 +0100
+Subject: bpf: Prohibit alu ops for pointer types not defining ptr_limit
+
+From: Piotr Krysiuk <piotras@gmail.com>
+
+commit f232326f6966cf2a1d1db7bc917a4ce5f9f55f76 upstream.
+
+The purpose of this patch is to streamline error propagation and in particular
+to propagate retrieve_ptr_limit() errors for pointer types that are not defining
+a ptr_limit such that register-based alu ops against these types can be rejected.
+
+The main rationale is that a gap has been identified by Piotr in the existing
+protection against speculatively out-of-bounds loads, for example, in case of
+ctx pointers, unprivileged programs can still perform pointer arithmetic. This
+can be abused to execute speculatively out-of-bounds loads without restrictions
+and thus extract contents of kernel memory.
+
+Fix this by rejecting unprivileged programs that attempt any pointer arithmetic
+on unprotected pointer types. The two affected ones are pointer to ctx as well
+as pointer to map. Field access to a modified ctx' pointer is rejected at a
+later point in time in the verifier, and 7c6967326267 ("bpf: Permit map_ptr
+arithmetic with opcode add and offset 0") only relevant for root-only use cases.
+Risk of unprivileged program breakage is considered very low.
+
+Fixes: 7c6967326267 ("bpf: Permit map_ptr arithmetic with opcode add and offset 0")
+Fixes: b2157399cc98 ("bpf: prevent out-of-bounds speculation")
+Signed-off-by: Piotr Krysiuk <piotras@gmail.com>
+Co-developed-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/bpf/verifier.c |   16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -2104,6 +2104,7 @@ static int sanitize_ptr_alu(struct bpf_v
+       u32 alu_state, alu_limit;
+       struct bpf_reg_state tmp;
+       bool ret;
++      int err;
+       if (can_skip_alu_sanitation(env, insn))
+               return 0;
+@@ -2119,10 +2120,13 @@ static int sanitize_ptr_alu(struct bpf_v
+       alu_state |= ptr_is_dst_reg ?
+                    BPF_ALU_SANITIZE_SRC : BPF_ALU_SANITIZE_DST;
+-      if (retrieve_ptr_limit(ptr_reg, &alu_limit, opcode, off_is_neg))
+-              return 0;
+-      if (update_alu_sanitation_state(aux, alu_state, alu_limit))
+-              return -EACCES;
++      err = retrieve_ptr_limit(ptr_reg, &alu_limit, opcode, off_is_neg);
++      if (err < 0)
++              return err;
++
++      err = update_alu_sanitation_state(aux, alu_state, alu_limit);
++      if (err < 0)
++              return err;
+ do_sim:
+       /* Simulate and find potential out-of-bounds access under
+        * speculative execution from truncation as a result of
+@@ -2215,7 +2219,7 @@ static int adjust_ptr_min_max_vals(struc
+       case BPF_ADD:
+               ret = sanitize_ptr_alu(env, insn, ptr_reg, dst_reg, smin_val < 0);
+               if (ret < 0) {
+-                      verbose("R%d tried to add from different maps or paths\n", dst);
++                      verbose("R%d tried to add from different maps, paths, or prohibited types\n", dst);
+                       return ret;
+               }
+               /* We can take a fixed offset as long as it doesn't overflow
+@@ -2270,7 +2274,7 @@ static int adjust_ptr_min_max_vals(struc
+       case BPF_SUB:
+               ret = sanitize_ptr_alu(env, insn, ptr_reg, dst_reg, smin_val < 0);
+               if (ret < 0) {
+-                      verbose("R%d tried to sub from different maps or paths\n", dst);
++                      verbose("R%d tried to sub from different maps, paths, or prohibited types\n", dst);
+                       return ret;
+               }
+               if (dst_reg == off_reg) {
index b8bacb57800b767e7cc40093b13d9c492fe9a541..290f7788b37c39b9606fc42ec529b9f6fba7406e 100644 (file)
@@ -5,3 +5,4 @@ bpf-fix-off-by-one-for-area-size-in-creating-mask-to-left.patch
 bpf-simplify-alu_limit-masking-for-pointer-arithmetic.patch
 bpf-add-sanity-check-for-upper-ptr_limit.patch
 net-dsa-b53-support-setting-learning-on-port.patch
+bpf-prohibit-alu-ops-for-pointer-types-not-defining-ptr_limit.patch