linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: will.deacon@arm.com (Will Deacon)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 2/2] arm64: defconfig: enable BPF related configs
Date: Wed, 28 Nov 2018 20:01:39 +0000	[thread overview]
Message-ID: <20181128200138.GB32668@arm.com> (raw)
In-Reply-To: <20181127231839.GF30658@n2100.armlinux.org.uk>

[+Daniel and Alexei]

On Tue, Nov 27, 2018 at 11:18:39PM +0000, Russell King - ARM Linux wrote:
> On Tue, Nov 27, 2018 at 07:31:18PM +0000, Will Deacon wrote:
> > On Mon, Nov 26, 2018 at 03:52:47PM +0000, Russell King - ARM Linux wrote:
> > > Another point to consider is whether the BPF JIT creates code that
> > > is safe from Spectre, or whether it opens up more Spectre issues.
> > > If it isn't, maybe the better option is to disable kernel-side BPF
> > > entirely until it is fixed up.
> > > 
> > > I've raised that point for 32-bit ARM already, and the 32-bit ARM
> > > BPF JIT isn't going to have the Spectre mitigations applied (since
> > > no one appears interested whenever I've raised it.)  So, for 32-bit
> > > ARM, it's better to have kernel-side BPF entirely disabled if you
> > > care about Spectre mitigations.
> > 
> > I thought that the Spectre mitigations (at least for variant 1) were handled
> > by the core BPF JIT, as a result of b2157399cc98 ("bpf: prevent out-of-bounds
> > speculation")? I think we rely on randomization to protect against variant 2
> > for JITted code.
> > 
> > Did I miss something here?
> 
> It depends - there's at least one case in eBPF that requires the JIT to
> be mitigated, and that's the tail-call stuff.  That's prime Spectre
> exploitation territory, because the pseudocode for that eBPF instruction
> is:
> 
> 	if (index >= array->map.max_entries)
> 		goto out;
> 	if (tail_call_cnt > MAX_TAIL_CALL_CNT)
> 		goto out;
> 	tail_call_cnt++;
> 	prog = array->ptrs[index];
> 	if (prog == NULL)
> 		goto out;
> 	goto *(prog->bpf_func + prologue_size);
> 
> If 'index' is larger than map.max_entries, and we speculate past the
> goto, then out of bounds cache lines in the array->ptrs[] could be
> loaded.

It looks like the verifier rewrites the BPF instructions so that the
index is masked here:


	/* instead of changing every JIT dealing with tail_call
	 * emit two extra insns:
	 * if (index >= max_entries) goto out;
	 * index &= array->index_mask;
	 * to avoid out-of-bounds cpu speculation
	 */
	if (bpf_map_ptr_poisoned(aux)) {
		verbose(env, "tail_call abusing map_ptr\n");
		return -EINVAL;
	}

	map_ptr = BPF_MAP_PTR(aux->map_state);
	insn_buf[0] = BPF_JMP_IMM(BPF_JGE, BPF_REG_3,
			map_ptr->max_entries, 2);
	insn_buf[1] = BPF_ALU32_IMM(BPF_AND, BPF_REG_3,
			container_of(map_ptr,
				struct bpf_array,
				map)->index_mask);
	insn_buf[2] = *insn;
	cnt = 3;
	new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt);


so I think that should be ok. In the worst case, we have some redundant
bounds checking of the index in the arch code.

> In cBPF, it seems to me that there is enough support to do something
> like:
> 
> 	if (val > max)		// BPF_JMP | BPF_JGT | BPF_K
> 		jump somewhere;
> 	addr += val;		// BPF_ALU | BPF_ADD | BPF_W
> 	val2 = *addr;		// BPF_LDX | BPF_MEM | BPF_W
> 
> which looks to me like it can fit the Spectre exploitation pattern,
> but is much harder to work around than the eBPF tailcall (we would
> need to detect the BPF instruction sequence.)  I haven't validated
> that such a sequence is actually possible in cBPF, but as cBPF is
> used for packet filtering, and there's a need for it to support
> jumping over the headers which can be variable lengths, then I
> would not be surprised if such BPF sequences were possible.

I was under the impression that the BPF type system didn't allow you to
construct arbitrary addresses like that, but I must defer to the BPF
developers on the details.

Will

      reply	other threads:[~2018-11-28 20:01 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-11 18:10 [PATCH 1/2] ARM: multi_v7_defconfig: enable BPF related configs Peter Robinson
2018-11-11 18:10 ` [PATCH 2/2] arm64: defconfig: " Peter Robinson
2018-11-12 18:36   ` Will Deacon
2018-11-17 23:18     ` Ard Biesheuvel
2018-11-26 15:38       ` Will Deacon
2018-11-26 15:52         ` Russell King - ARM Linux
2018-11-27 19:31           ` Will Deacon
2018-11-27 23:18             ` Russell King - ARM Linux
2018-11-28 20:01               ` Will Deacon [this message]

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=20181128200138.GB32668@arm.com \
    --to=will.deacon@arm.com \
    --cc=linux-arm-kernel@lists.infradead.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).