stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: <gregkh@linuxfoundation.org>
To: daniel@iogearbox.net, ast@kernel.org, ecree@solarflare.com,
	gregkh@linuxfoundation.org, jannh@google.com
Cc: <stable@vger.kernel.org>, <stable-commits@vger.kernel.org>
Subject: Patch "[PATCH stable/4.14 08/14] bpf: fix incorrect tracking of register size truncation" has been added to the 4.14-stable tree
Date: Fri, 22 Dec 2017 16:47:43 +0100	[thread overview]
Message-ID: <1513957663252237@kroah.com> (raw)
In-Reply-To: <20171222152312.2945-9-daniel@iogearbox.net>


This is a note to let you know that I've just added the patch titled

    [PATCH stable/4.14 08/14] bpf: fix incorrect tracking of register size truncation

to the 4.14-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     bpf-fix-incorrect-tracking-of-register-size-truncation.patch
and it can be found in the queue-4.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.


>From foo@baz Fri Dec 22 16:47:02 CET 2017
From: Daniel Borkmann <daniel@iogearbox.net>
Date: Fri, 22 Dec 2017 16:23:06 +0100
Subject: [PATCH stable/4.14 08/14] bpf: fix incorrect tracking of register size truncation
To: gregkh@linuxfoundation.org
Cc: ast@kernel.org, daniel@iogearbox.net, jannh@google.com, stable@vger.kernel.org
Message-ID: <20171222152312.2945-9-daniel@iogearbox.net>

From: Daniel Borkmann <daniel@iogearbox.net>


From: Jann Horn <jannh@google.com>

[ Upstream commit 0c17d1d2c61936401f4702e1846e2c19b200f958 ]

Properly handle register truncation to a smaller size.

The old code first mirrors the clearing of the high 32 bits in the bitwise
tristate representation, which is correct. But then, it computes the new
arithmetic bounds as the intersection between the old arithmetic bounds and
the bounds resulting from the bitwise tristate representation. Therefore,
when coerce_reg_to_32() is called on a number with bounds
[0xffff'fff8, 0x1'0000'0007], the verifier computes
[0xffff'fff8, 0xffff'ffff] as bounds of the truncated number.
This is incorrect: The truncated number could also be in the range [0, 7],
and no meaningful arithmetic bounds can be computed in that case apart from
the obvious [0, 0xffff'ffff].

Starting with v4.14, this is exploitable by unprivileged users as long as
the unprivileged_bpf_disabled sysctl isn't set.

Debian assigned CVE-2017-16996 for this issue.

v2:
 - flip the mask during arithmetic bounds calculation (Ben Hutchings)
v3:
 - add CVE number (Ben Hutchings)

Fixes: b03c9f9fdc37 ("bpf/verifier: track signed and unsigned min/max values")
Signed-off-by: Jann Horn <jannh@google.com>
Acked-by: Edward Cree <ecree@solarflare.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/bpf/verifier.c |   44 +++++++++++++++++++++++++++-----------------
 1 file changed, 27 insertions(+), 17 deletions(-)

--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1068,6 +1068,29 @@ static int check_ptr_alignment(struct bp
 	return check_generic_ptr_alignment(reg, pointer_desc, off, size, strict);
 }
 
+/* truncate register to smaller size (in bytes)
+ * must be called with size < BPF_REG_SIZE
+ */
+static void coerce_reg_to_size(struct bpf_reg_state *reg, int size)
+{
+	u64 mask;
+
+	/* clear high bits in bit representation */
+	reg->var_off = tnum_cast(reg->var_off, size);
+
+	/* fix arithmetic bounds */
+	mask = ((u64)1 << (size * 8)) - 1;
+	if ((reg->umin_value & ~mask) == (reg->umax_value & ~mask)) {
+		reg->umin_value &= mask;
+		reg->umax_value &= mask;
+	} else {
+		reg->umin_value = 0;
+		reg->umax_value = mask;
+	}
+	reg->smin_value = reg->umin_value;
+	reg->smax_value = reg->umax_value;
+}
+
 /* check whether memory at (regno + off) is accessible for t = (read | write)
  * if t==write, value_regno is a register which value is stored into memory
  * if t==read, value_regno is a register which will receive the value from memory
@@ -1200,9 +1223,7 @@ static int check_mem_access(struct bpf_v
 	if (!err && size < BPF_REG_SIZE && value_regno >= 0 && t == BPF_READ &&
 	    state->regs[value_regno].type == SCALAR_VALUE) {
 		/* b/h/w load zero-extends, mark upper bits as known 0 */
-		state->regs[value_regno].var_off = tnum_cast(
-					state->regs[value_regno].var_off, size);
-		__update_reg_bounds(&state->regs[value_regno]);
+		coerce_reg_to_size(&state->regs[value_regno], size);
 	}
 	return err;
 }
@@ -1742,14 +1763,6 @@ static int check_call(struct bpf_verifie
 	return 0;
 }
 
-static void coerce_reg_to_32(struct bpf_reg_state *reg)
-{
-	/* clear high 32 bits */
-	reg->var_off = tnum_cast(reg->var_off, 4);
-	/* Update bounds */
-	__update_reg_bounds(reg);
-}
-
 static bool signed_add_overflows(s64 a, s64 b)
 {
 	/* Do the add in u64, where overflow is well-defined */
@@ -1984,8 +1997,8 @@ static int adjust_scalar_min_max_vals(st
 
 	if (BPF_CLASS(insn->code) != BPF_ALU64) {
 		/* 32-bit ALU ops are (32,32)->64 */
-		coerce_reg_to_32(dst_reg);
-		coerce_reg_to_32(&src_reg);
+		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;
@@ -2364,10 +2377,7 @@ static int check_alu_op(struct bpf_verif
 					return -EACCES;
 				}
 				mark_reg_unknown(regs, insn->dst_reg);
-				/* high 32 bits are known zero. */
-				regs[insn->dst_reg].var_off = tnum_cast(
-						regs[insn->dst_reg].var_off, 4);
-				__update_reg_bounds(&regs[insn->dst_reg]);
+				coerce_reg_to_size(&regs[insn->dst_reg], 4);
 			}
 		} else {
 			/* case: R = imm


Patches currently in stable-queue which might be from daniel@iogearbox.net are

queue-4.14/bpf-fix-integer-overflows.patch
queue-4.14/bpf-fix-branch-pruning-logic.patch
queue-4.14/bpf-s390x-do-not-reload-skb-pointers-in-non-skb-context.patch
queue-4.14/bpf-sparc-fix-usage-of-wrong-reg-for-load_skb_regs-after-call.patch
queue-4.14/bpf-fix-incorrect-tracking-of-register-size-truncation.patch
queue-4.14/bpf-don-t-prune-branches-when-a-scalar-is-replaced-with-a-pointer.patch
queue-4.14/bpf-verifier-fix-bounds-calculation-on-bpf_rsh.patch
queue-4.14/selftests-bpf-add-tests-for-recent-bugfixes.patch
queue-4.14/bpf-fix-corruption-on-concurrent-perf_event_output-calls.patch
queue-4.14/bpf-fix-incorrect-sign-extension-in-check_alu_op.patch
queue-4.14/bpf-ppc64-do-not-reload-skb-pointers-in-non-skb-context.patch
queue-4.14/bpf-fix-missing-error-return-in-check_stack_boundary.patch
queue-4.14/bpf-force-strict-alignment-checks-for-stack-pointers.patch
queue-4.14/bpf-fix-32-bit-alu-op-verification.patch
queue-4.14/bpf-fix-build-issues-on-um-due-to-mising-bpf_perf_event.h.patch

  reply	other threads:[~2017-12-22 15:47 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-22 15:22 [PATCH stable/4.14 00/14] BPF stable patches for 4.14 Daniel Borkmann
2017-12-22 15:22 ` [PATCH stable/4.14 01/14] bpf: fix branch pruning logic Daniel Borkmann
2017-12-22 15:47   ` Patch "[PATCH stable/4.14 01/14] bpf: fix branch pruning logic" has been added to the 4.14-stable tree gregkh
2017-12-22 15:23 ` [PATCH stable/4.14 02/14] bpf: fix corruption on concurrent perf_event_output calls Daniel Borkmann
2017-12-22 15:47   ` Patch "[PATCH stable/4.14 02/14] bpf: fix corruption on concurrent perf_event_output calls" has been added to the 4.14-stable tree gregkh
2017-12-22 15:23 ` [PATCH stable/4.14 03/14] bpf, s390x: do not reload skb pointers in non-skb context Daniel Borkmann
2017-12-22 15:47   ` Patch "[PATCH stable/4.14 03/14] bpf, s390x: do not reload skb pointers in non-skb context" has been added to the 4.14-stable tree gregkh
2017-12-22 15:23 ` [PATCH stable/4.14 04/14] bpf, ppc64: do not reload skb pointers in non-skb context Daniel Borkmann
2017-12-22 15:47   ` Patch "[PATCH stable/4.14 04/14] bpf, ppc64: do not reload skb pointers in non-skb context" has been added to the 4.14-stable tree gregkh
2017-12-22 15:23 ` [PATCH stable/4.14 05/14] bpf, sparc: fix usage of wrong reg for load_skb_regs after call Daniel Borkmann
2017-12-22 15:47   ` Patch "[PATCH stable/4.14 05/14] bpf, sparc: fix usage of wrong reg for load_skb_regs after call" has been added to the 4.14-stable tree gregkh
2017-12-22 15:23 ` [PATCH stable/4.14 06/14] bpf/verifier: fix bounds calculation on BPF_RSH Daniel Borkmann
2017-12-22 15:47   ` Patch "[PATCH stable/4.14 06/14] bpf/verifier: fix bounds calculation on BPF_RSH" has been added to the 4.14-stable tree gregkh
2017-12-22 15:23 ` [PATCH stable/4.14 07/14] bpf: fix incorrect sign extension in check_alu_op() Daniel Borkmann
2017-12-22 15:47   ` Patch "[PATCH stable/4.14 07/14] bpf: fix incorrect sign extension in check_alu_op()" has been added to the 4.14-stable tree gregkh
2017-12-22 15:23 ` [PATCH stable/4.14 08/14] bpf: fix incorrect tracking of register size truncation Daniel Borkmann
2017-12-22 15:47   ` gregkh [this message]
2017-12-22 15:23 ` [PATCH stable/4.14 09/14] bpf: fix 32-bit ALU op verification Daniel Borkmann
2017-12-22 15:47   ` Patch "[PATCH stable/4.14 09/14] bpf: fix 32-bit ALU op verification" has been added to the 4.14-stable tree gregkh
2017-12-22 15:23 ` [PATCH stable/4.14 10/14] bpf: fix missing error return in check_stack_boundary() Daniel Borkmann
2017-12-22 15:47   ` Patch "[PATCH stable/4.14 10/14] bpf: fix missing error return in check_stack_boundary()" has been added to the 4.14-stable tree gregkh
2017-12-22 15:23 ` [PATCH stable/4.14 11/14] bpf: force strict alignment checks for stack pointers Daniel Borkmann
2017-12-22 15:47   ` Patch "[PATCH stable/4.14 11/14] bpf: force strict alignment checks for stack pointers" has been added to the 4.14-stable tree gregkh
2017-12-22 15:23 ` [PATCH stable/4.14 12/14] bpf: don't prune branches when a scalar is replaced with a pointer Daniel Borkmann
2017-12-22 15:47   ` Patch "[PATCH stable/4.14 12/14] bpf: don't prune branches when a scalar is replaced with a pointer" has been added to the 4.14-stable tree gregkh
2017-12-22 15:23 ` [PATCH stable/4.14 13/14] bpf: fix integer overflows Daniel Borkmann
2017-12-22 15:47   ` Patch "[PATCH stable/4.14 13/14] bpf: fix integer overflows" has been added to the 4.14-stable tree gregkh
2017-12-22 15:23 ` [PATCH stable/4.14 14/14] selftests/bpf: add tests for recent bugfixes Daniel Borkmann
2017-12-22 15:47   ` Patch "[PATCH stable/4.14 14/14] selftests/bpf: add tests for recent bugfixes" has been added to the 4.14-stable tree gregkh
2017-12-22 15:45 ` [PATCH stable/4.14 00/14] BPF stable patches for 4.14 Greg KH
2017-12-22 15:48   ` Greg KH
2017-12-22 15:51 ` Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1513957663252237@kroah.com \
    --to=gregkh@linuxfoundation.org \
    --cc=ast@kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=ecree@solarflare.com \
    --cc=jannh@google.com \
    --cc=stable-commits@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).