stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org,
	syzbot+3d0b2441dbb71751615e@syzkaller.appspotmail.com,
	syzbot+c8504affd4fdd0c1b626@syzkaller.appspotmail.com,
	syzbot+e5190cb881d8660fb1a3@syzkaller.appspotmail.com,
	syzbot+efae31b384d5badbd620@syzkaller.appspotmail.com,
	Daniel Borkmann <daniel@iogearbox.net>,
	Alexei Starovoitov <ast@kernel.org>, Yonghong Song <yhs@fb.com>,
	Edward Cree <ecree@solarflare.com>
Subject: [PATCH 4.17 01/67] bpf: reject passing modified ctx to helper functions
Date: Mon, 16 Jul 2018 09:34:30 +0200	[thread overview]
Message-ID: <20180716073443.443235403@linuxfoundation.org> (raw)
In-Reply-To: <20180716073443.294323458@linuxfoundation.org>

4.17-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Daniel Borkmann <daniel@iogearbox.net>

commit 58990d1ff3f7896ee341030e9a7c2e4002570683 upstream.

As commit 28e33f9d78ee ("bpf: disallow arithmetic operations on
context pointer") already describes, f1174f77b50c ("bpf/verifier:
rework value tracking") removed the specific white-listed cases
we had previously where we would allow for pointer arithmetic in
order to further generalize it, and allow e.g. context access via
modified registers. While the dereferencing of modified context
pointers had been forbidden through 28e33f9d78ee, syzkaller did
recently manage to trigger several KASAN splats for slab out of
bounds access and use after frees by simply passing a modified
context pointer to a helper function which would then do the bad
access since verifier allowed it in adjust_ptr_min_max_vals().

Rejecting arithmetic on ctx pointer in adjust_ptr_min_max_vals()
generally could break existing programs as there's a valid use
case in tracing in combination with passing the ctx to helpers as
bpf_probe_read(), where the register then becomes unknown at
verification time due to adding a non-constant offset to it. An
access sequence may look like the following:

  offset = args->filename;  /* field __data_loc filename */
  bpf_probe_read(&dst, len, (char *)args + offset); // args is ctx

There are two options: i) we could special case the ctx and as
soon as we add a constant or bounded offset to it (hence ctx type
wouldn't change) we could turn the ctx into an unknown scalar, or
ii) we generalize the sanity test for ctx member access into a
small helper and assert it on the ctx register that was passed
as a function argument. Fwiw, latter is more obvious and less
complex at the same time, and one case that may potentially be
legitimate in future for ctx member access at least would be for
ctx to carry a const offset. Therefore, fix follows approach
from ii) and adds test cases to BPF kselftests.

Fixes: f1174f77b50c ("bpf/verifier: rework value tracking")
Reported-by: syzbot+3d0b2441dbb71751615e@syzkaller.appspotmail.com
Reported-by: syzbot+c8504affd4fdd0c1b626@syzkaller.appspotmail.com
Reported-by: syzbot+e5190cb881d8660fb1a3@syzkaller.appspotmail.com
Reported-by: syzbot+efae31b384d5badbd620@syzkaller.appspotmail.com
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Yonghong Song <yhs@fb.com>
Acked-by: Edward Cree <ecree@solarflare.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 kernel/bpf/verifier.c                       |   48 ++++++++++++++---------
 tools/testing/selftests/bpf/test_verifier.c |   58 +++++++++++++++++++++++++++-
 2 files changed, 88 insertions(+), 18 deletions(-)

--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1610,6 +1610,30 @@ static int get_callee_stack_depth(struct
 }
 #endif
 
+static int check_ctx_reg(struct bpf_verifier_env *env,
+			 const struct bpf_reg_state *reg, int regno)
+{
+	/* Access to ctx or passing it to a helper is only allowed in
+	 * its original, unmodified form.
+	 */
+
+	if (reg->off) {
+		verbose(env, "dereference of modified ctx ptr R%d off=%d disallowed\n",
+			regno, reg->off);
+		return -EACCES;
+	}
+
+	if (!tnum_is_const(reg->var_off) || reg->var_off.value) {
+		char tn_buf[48];
+
+		tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
+		verbose(env, "variable ctx access var_off=%s disallowed\n", tn_buf);
+		return -EACCES;
+	}
+
+	return 0;
+}
+
 /* truncate register to smaller size (in bytes)
  * must be called with size < BPF_REG_SIZE
  */
@@ -1679,24 +1703,11 @@ static int check_mem_access(struct bpf_v
 			verbose(env, "R%d leaks addr into ctx\n", value_regno);
 			return -EACCES;
 		}
-		/* ctx accesses must be at a fixed offset, so that we can
-		 * determine what type of data were returned.
-		 */
-		if (reg->off) {
-			verbose(env,
-				"dereference of modified ctx ptr R%d off=%d+%d, ctx+const is allowed, ctx+const+const is not\n",
-				regno, reg->off, off - reg->off);
-			return -EACCES;
-		}
-		if (!tnum_is_const(reg->var_off) || reg->var_off.value) {
-			char tn_buf[48];
 
-			tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
-			verbose(env,
-				"variable ctx access var_off=%s off=%d size=%d",
-				tn_buf, off, size);
-			return -EACCES;
-		}
+		err = check_ctx_reg(env, reg, regno);
+		if (err < 0)
+			return err;
+
 		err = check_ctx_access(env, insn_idx, off, size, t, &reg_type);
 		if (!err && t == BPF_READ && value_regno >= 0) {
 			/* ctx access returns either a scalar, or a
@@ -1977,6 +1988,9 @@ static int check_func_arg(struct bpf_ver
 		expected_type = PTR_TO_CTX;
 		if (type != expected_type)
 			goto err_type;
+		err = check_ctx_reg(env, reg, regno);
+		if (err < 0)
+			return err;
 	} else if (arg_type_is_mem_ptr(arg_type)) {
 		expected_type = PTR_TO_STACK;
 		/* One exception here. In case function allows for NULL to be
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -8190,7 +8190,7 @@ static struct bpf_test tests[] = {
 				    offsetof(struct __sk_buff, mark)),
 			BPF_EXIT_INSN(),
 		},
-		.errstr = "dereference of modified ctx ptr R1 off=68+8, ctx+const is allowed, ctx+const+const is not",
+		.errstr = "dereference of modified ctx ptr",
 		.result = REJECT,
 		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
 	},
@@ -11423,6 +11423,62 @@ static struct bpf_test tests[] = {
 		.errstr = "BPF_XADD stores into R2 packet",
 		.prog_type = BPF_PROG_TYPE_XDP,
 	},
+	{
+		"pass unmodified ctx pointer to helper",
+		.insns = {
+			BPF_MOV64_IMM(BPF_REG_2, 0),
+			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+				     BPF_FUNC_csum_update),
+			BPF_MOV64_IMM(BPF_REG_0, 0),
+			BPF_EXIT_INSN(),
+		},
+		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
+		.result = ACCEPT,
+	},
+	{
+		"pass modified ctx pointer to helper, 1",
+		.insns = {
+			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -612),
+			BPF_MOV64_IMM(BPF_REG_2, 0),
+			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+				     BPF_FUNC_csum_update),
+			BPF_MOV64_IMM(BPF_REG_0, 0),
+			BPF_EXIT_INSN(),
+		},
+		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
+		.result = REJECT,
+		.errstr = "dereference of modified ctx ptr",
+	},
+	{
+		"pass modified ctx pointer to helper, 2",
+		.insns = {
+			BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -612),
+			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+				     BPF_FUNC_get_socket_cookie),
+			BPF_MOV64_IMM(BPF_REG_0, 0),
+			BPF_EXIT_INSN(),
+		},
+		.result_unpriv = REJECT,
+		.result = REJECT,
+		.errstr_unpriv = "dereference of modified ctx ptr",
+		.errstr = "dereference of modified ctx ptr",
+	},
+	{
+		"pass modified ctx pointer to helper, 3",
+		.insns = {
+			BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 0),
+			BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 4),
+			BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
+			BPF_MOV64_IMM(BPF_REG_2, 0),
+			BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+				     BPF_FUNC_csum_update),
+			BPF_MOV64_IMM(BPF_REG_0, 0),
+			BPF_EXIT_INSN(),
+		},
+		.prog_type = BPF_PROG_TYPE_SCHED_CLS,
+		.result = REJECT,
+		.errstr = "variable ctx access var_off=(0x0; 0x4)",
+	},
 };
 
 static int probe_filter_length(const struct bpf_insn *fp)

  reply	other threads:[~2018-07-16  8:01 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-16  7:34 [PATCH 4.17 00/67] 4.17.7-stable review Greg Kroah-Hartman
2018-07-16  7:34 ` Greg Kroah-Hartman [this message]
2018-07-16  7:34 ` [PATCH 4.17 02/67] MIPS: Call dump_stack() from show_regs() Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 03/67] MIPS: Use async IPIs for arch_trigger_cpumask_backtrace() Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 04/67] MIPS: Fix ioremap() RAM check Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 05/67] drm/etnaviv: Check for platform_device_register_simple() failure Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 06/67] drm/etnaviv: Fix driver unregistering Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 07/67] drm/etnaviv: bring back progress check in job timeout handler Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 09/67] mmc: sdhci-esdhc-imx: allow 1.8V modes without 100/200MHz pinctrl states Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 10/67] mmc: dw_mmc: fix card threshold control configuration Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 11/67] mmc: renesas_sdhi_internal_dmac: Cannot clear the RX_IN_USE in abort Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 12/67] ibmasm: dont write out of bounds in read handler Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 13/67] staging: rtl8723bs: Prevent an underflow in rtw_check_beacon_data() Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 14/67] staging: r8822be: Fix RTL8822be cant find any wireless AP Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 15/67] ata: Fix ZBC_OUT command block check Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 16/67] ata: Fix ZBC_OUT all bit handling Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 17/67] mei: discard messages from not connected client during power down Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 18/67] mtd: spi-nor: cadence-quadspi: Fix direct mode write timeouts Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 19/67] tracing/kprobe: Release kprobe print_fmt properly Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 20/67] vmw_balloon: fix inflation with batching Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 21/67] ahci: Add Intel Ice Lake LP PCI ID Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 22/67] ahci: Disable LPM on Lenovo 50 series laptops with a too old BIOS Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 23/67] thunderbolt: Notify userspace when boot_acl is changed Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 24/67] USB: serial: ch341: fix type promotion bug in ch341_control_in() Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 25/67] USB: serial: cp210x: add another USB ID for Qivicon ZigBee stick Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 26/67] USB: serial: keyspan_pda: fix modem-status error handling Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 27/67] USB: yurex: fix out-of-bounds uaccess in read handler Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 28/67] USB: serial: mos7840: fix status-register error handling Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 29/67] usb: quirks: add delay quirks for Corsair Strafe Greg Kroah-Hartman
2018-07-16  7:34 ` [PATCH 4.17 30/67] xhci: xhci-mem: off by one in xhci_stream_id_to_ring() Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 31/67] Fix up non-directory creation in SGID directories Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 32/67] mm: zero unavailable pages before memmap init Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 33/67] ALSA: hda/realtek - two more lenovo models need fixup of MIC_LOCATION Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 34/67] ALSA: hda - Handle pm failure during hotplug Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 35/67] mm: do not drop unused pages when userfaultd is running Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 36/67] fs/proc/task_mmu.c: fix Locked field in /proc/pid/smaps* Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 37/67] x86/purgatory: add missing FORCE to Makefile target Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 38/67] fs, elf: make sure to page align bss in load_elf_library Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 39/67] mm: do not bug_on on incorrect length in __mm_populate() Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 40/67] tracing: Reorder display of TGID to be after PID Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 41/67] kbuild: delete INSTALL_FW_PATH from kbuild documentation Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 42/67] acpi, nfit: Fix scrub idle detection Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 43/67] arm64: neon: Fix function may_use_simd() return error status Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 44/67] tools build: fix # escaping in .cmd files for future Make Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 45/67] IB/hfi1: Fix incorrect mixing of ERR_PTR and NULL return values Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 46/67] i2c: tegra: Fix NACK error handling Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 47/67] i2c: recovery: if possible send STOP with recovery pulses Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 48/67] iw_cxgb4: correctly enforce the max reg_mr depth Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 49/67] xen: remove global bit from __default_kernel_pte_mask for pv guests Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 50/67] xen: setup pv irq ops vector earlier Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 51/67] bsg: fix bogus EINVAL on non-data commands Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 52/67] crypto: x86/salsa20 - remove x86 salsa20 implementations Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 53/67] uprobes/x86: Remove incorrect WARN_ON() in uprobe_init_insn() Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 54/67] netfilter: nf_queue: augment nfqa_cfg_policy Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 55/67] crypto: dont optimize keccakf() Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 56/67] netfilter: x_tables: initialise match/target check parameter struct Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 57/67] loop: add recursion validation to LOOP_CHANGE_FD Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 58/67] xfs: fix inobt magic number check Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 59/67] PM / hibernate: Fix oops at snapshot_write() Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 60/67] RDMA/ucm: Mark UCM interface as BROKEN Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 61/67] loop: remember whether sysfs_create_group() was done Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 63/67] f2fs: give message and set need_fsck given broken node id Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 64/67] f2fs: avoid bug_on on corrupted inode Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 65/67] f2fs: sanity check on sit entry Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 66/67] f2fs: sanity check for total valid node blocks Greg Kroah-Hartman
2018-07-16  7:35 ` [PATCH 4.17 67/67] ARM: dts: armada-38x: use the new thermal binding Greg Kroah-Hartman
2018-07-16 16:33 ` [PATCH 4.17 00/67] 4.17.7-stable review Guenter Roeck
2018-07-16 16:40   ` Nathan Chancellor
2018-07-16 16:48     ` Guenter Roeck
2018-07-16 16:44   ` Greg Kroah-Hartman
     [not found] ` <20180716073453.739013579@linuxfoundation.org>
2018-07-16 17:09   ` [PATCH 4.17 62/67] kvm: vmx: Nested VM-entry prereqs for event inj Marc Orr
2018-07-16 17:58 ` [PATCH 4.17 00/67] 4.17.7-stable review Naresh Kamboju
2018-07-16 21:31   ` [LTP] " Jan Stancek
2018-07-17  1:23     ` Dave Chinner
2018-07-17  9:41     ` Greg Kroah-Hartman

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=20180716073443.443235403@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=ast@kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=ecree@solarflare.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=syzbot+3d0b2441dbb71751615e@syzkaller.appspotmail.com \
    --cc=syzbot+c8504affd4fdd0c1b626@syzkaller.appspotmail.com \
    --cc=syzbot+e5190cb881d8660fb1a3@syzkaller.appspotmail.com \
    --cc=syzbot+efae31b384d5badbd620@syzkaller.appspotmail.com \
    --cc=yhs@fb.com \
    /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).