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
prev parent 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).