All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Jann Horn <jannh@google.com>, Alexei Starovoitov <ast@kernel.org>,
	Sasha Levin <sashal@kernel.org>,
	netdev@vger.kernel.org, linux-api@vger.kernel.org
Subject: [PATCH AUTOSEL 5.6 52/79] bpf: Forbid XADD on spilled pointers for unprivileged users
Date: Thu, 30 Apr 2020 09:50:16 -0400	[thread overview]
Message-ID: <20200430135043.19851-52-sashal@kernel.org> (raw)
In-Reply-To: <20200430135043.19851-1-sashal@kernel.org>

From: Jann Horn <jannh@google.com>

[ Upstream commit 6e7e63cbb023976d828cdb22422606bf77baa8a9 ]

When check_xadd() verifies an XADD operation on a pointer to a stack slot
containing a spilled pointer, check_stack_read() verifies that the read,
which is part of XADD, is valid. However, since the placeholder value -1 is
passed as `value_regno`, check_stack_read() can only return a binary
decision and can't return the type of the value that was read. The intent
here is to verify whether the value read from the stack slot may be used as
a SCALAR_VALUE; but since check_stack_read() doesn't check the type, and
the type information is lost when check_stack_read() returns, this is not
enforced, and a malicious user can abuse XADD to leak spilled kernel
pointers.

Fix it by letting check_stack_read() verify that the value is usable as a
SCALAR_VALUE if no type information is passed to the caller.

To be able to use __is_pointer_value() in check_stack_read(), move it up.

Fix up the expected unprivileged error message for a BPF selftest that,
until now, assumed that unprivileged users can use XADD on stack-spilled
pointers. This also gives us a test for the behavior introduced in this
patch for free.

In theory, this could also be fixed by forbidding XADD on stack spills
entirely, since XADD is a locked operation (for operations on memory with
concurrency) and there can't be any concurrency on the BPF stack; but
Alexei has said that he wants to keep XADD on stack slots working to avoid
changes to the test suite [1].

The following BPF program demonstrates how to leak a BPF map pointer as an
unprivileged user using this bug:

    // r7 = map_pointer
    BPF_LD_MAP_FD(BPF_REG_7, small_map),
    // r8 = launder(map_pointer)
    BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_7, -8),
    BPF_MOV64_IMM(BPF_REG_1, 0),
    ((struct bpf_insn) {
      .code  = BPF_STX | BPF_DW | BPF_XADD,
      .dst_reg = BPF_REG_FP,
      .src_reg = BPF_REG_1,
      .off = -8
    }),
    BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_FP, -8),

    // store r8 into map
    BPF_MOV64_REG(BPF_REG_ARG1, BPF_REG_7),
    BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
    BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -4),
    BPF_ST_MEM(BPF_W, BPF_REG_ARG2, 0, 0),
    BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
    BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
    BPF_EXIT_INSN(),
    BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_8, 0),

    BPF_MOV64_IMM(BPF_REG_0, 0),
    BPF_EXIT_INSN()

[1] https://lore.kernel.org/bpf/20200416211116.qxqcza5vo2ddnkdq@ast-mbp.dhcp.thefacebook.com/

Fixes: 17a5267067f3 ("bpf: verifier (add verifier core)")
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20200417000007.10734-1-jannh@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/verifier.c                         | 28 +++++++++++++------
 .../bpf/verifier/value_illegal_alu.c          |  1 +
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index e5d12c54b552c..e4357a301fb8f 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1918,6 +1918,15 @@ static bool register_is_const(struct bpf_reg_state *reg)
 	return reg->type == SCALAR_VALUE && tnum_is_const(reg->var_off);
 }
 
+static bool __is_pointer_value(bool allow_ptr_leaks,
+			       const struct bpf_reg_state *reg)
+{
+	if (allow_ptr_leaks)
+		return false;
+
+	return reg->type != SCALAR_VALUE;
+}
+
 static void save_register_state(struct bpf_func_state *state,
 				int spi, struct bpf_reg_state *reg)
 {
@@ -2108,6 +2117,16 @@ static int check_stack_read(struct bpf_verifier_env *env,
 			 * which resets stack/reg liveness for state transitions
 			 */
 			state->regs[value_regno].live |= REG_LIVE_WRITTEN;
+		} else if (__is_pointer_value(env->allow_ptr_leaks, reg)) {
+			/* If value_regno==-1, the caller is asking us whether
+			 * it is acceptable to use this value as a SCALAR_VALUE
+			 * (e.g. for XADD).
+			 * We must not allow unprivileged callers to do that
+			 * with spilled pointers.
+			 */
+			verbose(env, "leaking pointer from stack off %d\n",
+				off);
+			return -EACCES;
 		}
 		mark_reg_read(env, reg, reg->parent, REG_LIVE_READ64);
 	} else {
@@ -2473,15 +2492,6 @@ static int check_sock_access(struct bpf_verifier_env *env, int insn_idx,
 	return -EACCES;
 }
 
-static bool __is_pointer_value(bool allow_ptr_leaks,
-			       const struct bpf_reg_state *reg)
-{
-	if (allow_ptr_leaks)
-		return false;
-
-	return reg->type != SCALAR_VALUE;
-}
-
 static struct bpf_reg_state *reg_state(struct bpf_verifier_env *env, int regno)
 {
 	return cur_regs(env) + regno;
diff --git a/tools/testing/selftests/bpf/verifier/value_illegal_alu.c b/tools/testing/selftests/bpf/verifier/value_illegal_alu.c
index 7f6c232cd8423..ed1c2cea1dea6 100644
--- a/tools/testing/selftests/bpf/verifier/value_illegal_alu.c
+++ b/tools/testing/selftests/bpf/verifier/value_illegal_alu.c
@@ -88,6 +88,7 @@
 	BPF_EXIT_INSN(),
 	},
 	.fixup_map_hash_48b = { 3 },
+	.errstr_unpriv = "leaking pointer from stack off -8",
 	.errstr = "R0 invalid mem access 'inv'",
 	.result = REJECT,
 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
-- 
2.20.1


  parent reply	other threads:[~2020-04-30 14:09 UTC|newest]

Thread overview: 115+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-30 13:49 [PATCH AUTOSEL 5.6 01/79] ARM: dts: OMAP3: disable RNG on N950/N9 Sasha Levin
2020-04-30 13:49 ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 02/79] drm/bridge: analogix_dp: Split bind() into probe() and real bind() Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 03/79] ARM: dts: bcm283x: Add cells encoding format to firmware bus Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 04/79] iio:ad7797: Use correct attribute_group Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 05/79] iio: imu: st_lsm6dsx: fix read misalignment on untagged FIFO Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 06/79] iio: imu: st_lsm6dsx: specify slave odr in slv_odr Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 07/79] ASoC: topology: Add missing memory checks Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 08/79] ASoC: topology: Check return value of soc_tplg_create_tlv Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 09/79] ASoC: topology: Check return value of soc_tplg_*_create Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 10/79] ASoC: topology: Check soc_tplg_add_route return value Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 11/79] ASoC: topology: Check return value of pcm_new_ver Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 12/79] ASoC: topology: Check return value of soc_tplg_dai_config Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 13/79] nfsd: memory corruption in nfsd4_lock() Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 14/79] SUNRPC/cache: Fix unsafe traverse caused double-free in cache_purge Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 15/79] selftests: vm: Do not override definition of ARCH Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 16/79] selftests: vm: Fix 64-bit test builds for powerpc64le Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 17/79] ASoC: samsung: s3c24xx-i2s: Fix build after removal of DAI suspend/resume Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 18/79] Revert "Kernel selftests: tpm2: check for tpm support" Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 19/79] selftests/ipc: Fix test failure seen after initial test run Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 20/79] drm/bridge: anx6345: set correct BPC for display_info of connector Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 21/79] scsi: sg: add sg_remove_request in sg_write Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 22/79] drivers: soc: xilinx: fix firmware driver Kconfig dependency Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 23/79] drm/scheduler: fix drm_sched_get_cleanup_job Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 24/79] ASoC: sgtl5000: Fix VAG power-on handling Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 25/79] ASoC: q6dsp6: q6afe-dai: add missing channels to MI2S DAIs Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 26/79] ASoC: topology: Fix endianness issue Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 27/79] usb: dwc3: gadget: Properly set maxpacket limit Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 28/79] usb: dwc3: gadget: Do link recovery for SS and SSP Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 29/79] ASoC: rsnd: Fix parent SSI start/stop in multi-SSI mode Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 30/79] ASoC: rsnd: Fix HDMI channel mapping for " Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 31/79] ASoC: codecs: hdac_hdmi: Fix incorrect use of list_for_each_entry Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 32/79] ARM: dts: bcm283x: Disable dsi0 node Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 33/79] remoteproc: qcom_q6v5_mss: fix a bug in q6v5_probe() Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 34/79] usb: gadget: udc: atmel: Fix vbus disconnect handling Sasha Levin
2020-04-30 13:49   ` Sasha Levin
2020-04-30 13:49 ` [PATCH AUTOSEL 5.6 35/79] svcrdma: Fix trace point use-after-free race Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 36/79] ASoC: stm32: sai: fix sai probe Sasha Levin
2020-04-30 13:50   ` Sasha Levin
2020-04-30 13:50   ` Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 37/79] ASoC: SOF: Intel: add min/max channels for SSP on Baytrail/Broadwell Sasha Levin
2020-04-30 13:50   ` Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 38/79] drm/amd/powerplay: fix resume failed as smu table initialize early exit Sasha Levin
2020-04-30 13:50   ` Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 39/79] drm/amdgpu: Correctly initialize thermal controller for GPUs with Powerplay table v0 (e.g Hawaii) Sasha Levin
2020-04-30 13:50   ` Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 40/79] wimax/i2400m: Fix potential urb refcnt leak Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 41/79] net: stmmac: fix enabling socfpga's ptp_ref_clock Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 42/79] net: stmmac: Fix sub-second increment Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 43/79] netfilter: nat: fix error handling upon registering inet hook Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 44/79] counter: 104-quad-8: Add lock guards - generic interface Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 45/79] ASoC: meson: axg-card: fix codec-to-codec link setup Sasha Levin
2020-04-30 13:50   ` Sasha Levin
2020-04-30 13:56   ` Mark Brown
2020-04-30 13:56     ` Mark Brown
2020-05-02 13:46     ` Sasha Levin
2020-05-02 13:46       ` Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 46/79] ASoC: rsnd: Don't treat master SSI in multi SSI setup as parent Sasha Levin
2020-04-30 13:50   ` Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 47/79] ASoC: rsnd: Fix "status check failed" spam for multi-SSI Sasha Levin
2020-04-30 13:50   ` Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 48/79] net/mlx5: Fix failing fw tracer allocation on s390 Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 49/79] net/mlx5e: Don't trigger IRQ multiple times on XSK wakeup to avoid WQ overruns Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 50/79] net/mlx5e: Get the latest values from counters in switchdev mode Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 51/79] cpumap: Avoid warning when CONFIG_DEBUG_PER_CPU_MAPS is enabled Sasha Levin
2020-04-30 13:50 ` Sasha Levin [this message]
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 53/79] bpf: Fix handling of XADD on BTF memory Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 54/79] bpf, x86: Fix encoding for lower 8-bit registers in BPF_STX BPF_B Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 55/79] iwlwifi: actually check allocated conf_tlv pointer Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 56/79] ASoC: wm8960: Fix wrong clock after suspend & resume Sasha Levin
2020-04-30 13:50   ` Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 57/79] cifs: protect updating server->dstaddr with a spinlock Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 58/79] blk-iocost: Fix error on iocost_ioc_vrate_adj Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 59/79] s390/ftrace: fix potential crashes when switching tracers Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 60/79] scripts/config: allow colons in option strings for sed Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 61/79] sched/core: Fix reset-on-fork from RT with uclamp Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 62/79] perf/core: fix parent pid/tid in task exit events Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 63/79] cifs: do not share tcons with DFS Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 64/79] tracing: Fix memory leaks in trace_events_hist.c Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 65/79] um: ensure `make ARCH=um mrproper` removes arch/$(SUBARCH)/include/generated/ Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 66/79] ftrace: Fix memory leak caused by not freeing entry in unregister_ftrace_direct() Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 67/79] net: phy: bcm84881: clear settings on link down Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 68/79] lib/mpi: Fix building for powerpc with clang Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 69/79] mac80211: sta_info: Add lockdep condition for RCU list usage Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 70/79] afs: Fix to actually set AFS_SERVER_FL_HAVE_EPOCH Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 71/79] afs: Make record checking use TASK_UNINTERRUPTIBLE when appropriate Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 72/79] net: bcmgenet: suppress warnings on failed Rx SKB allocations Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 73/79] net: systemport: " Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 74/79] bpf, x86_32: Fix incorrect encoding in BPF_LDX zero-extension Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 75/79] bpf, x86_32: Fix clobbering of dst for BPF_JSET Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 76/79] bpf, x86_32: Fix logic error in BPF_LDX zero-extension Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 77/79] bpf: Propagate expected_attach_type when verifying freplace programs Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 78/79] tools/runqslower: Ensure own vmlinux.h is picked up first Sasha Levin
2020-04-30 13:50 ` [PATCH AUTOSEL 5.6 79/79] selftests/bpf: Fix a couple of broken test_btf cases Sasha Levin

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=20200430135043.19851-52-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=ast@kernel.org \
    --cc=jannh@google.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.