2018-05-03 16:05:59

by Mark Rutland

[permalink] [raw]
Subject: [PATCH] bpf: fix possible spectre-v1 in find_and_alloc_map()

It's possible for userspace to control attr->map_type. Sanitize it when
using it as an array index to prevent an out-of-bounds value being used
under speculation.

Found by smatch.

Signed-off-by: Mark Rutland <[email protected]>
Cc: Alexei Starovoitov <[email protected]>
Cc: Dan Carpenter <[email protected]>
Cc: Daniel Borkmann <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: [email protected]
---
kernel/bpf/syscall.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)

I found this when running smatch over a v4.17-rc2 arm64 allyesconfig kernel.

IIUC this may allow for a speculative branch to an arbitrary gadget when we
subsequently call ops->map_alloc_check(attr).

Mark.

diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 4ca46df19c9a..8a7acd0dbeb6 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -26,6 +26,7 @@
#include <linux/cred.h>
#include <linux/timekeeping.h>
#include <linux/ctype.h>
+#include <linux/nospec.h>

#define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY || \
(map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
@@ -102,12 +103,14 @@ const struct bpf_map_ops bpf_map_offload_ops = {
static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
{
const struct bpf_map_ops *ops;
+ u32 type = attr->map_type;
struct bpf_map *map;
int err;

- if (attr->map_type >= ARRAY_SIZE(bpf_map_types))
+ if (type >= ARRAY_SIZE(bpf_map_types))
return ERR_PTR(-EINVAL);
- ops = bpf_map_types[attr->map_type];
+ type = array_index_nospec(type, ARRAY_SIZE(bpf_map_types));
+ ops = bpf_map_types[type];
if (!ops)
return ERR_PTR(-EINVAL);

@@ -122,7 +125,7 @@ static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
if (IS_ERR(map))
return map;
map->ops = ops;
- map->map_type = attr->map_type;
+ map->map_type = type;
return map;
}

--
2.11.0



2018-05-03 16:49:24

by David Miller

[permalink] [raw]
Subject: Re: [PATCH] bpf: fix possible spectre-v1 in find_and_alloc_map()

From: Mark Rutland <[email protected]>
Date: Thu, 3 May 2018 17:04:59 +0100

> It's possible for userspace to control attr->map_type. Sanitize it when
> using it as an array index to prevent an out-of-bounds value being used
> under speculation.
>
> Found by smatch.
>
> Signed-off-by: Mark Rutland <[email protected]>

Acked-by: David S. Miller <[email protected]>

2018-05-04 00:17:18

by Daniel Borkmann

[permalink] [raw]
Subject: Re: [PATCH] bpf: fix possible spectre-v1 in find_and_alloc_map()

On 05/03/2018 06:04 PM, Mark Rutland wrote:
> It's possible for userspace to control attr->map_type. Sanitize it when
> using it as an array index to prevent an out-of-bounds value being used
> under speculation.
>
> Found by smatch.
>
> Signed-off-by: Mark Rutland <[email protected]>
> Cc: Alexei Starovoitov <[email protected]>
> Cc: Dan Carpenter <[email protected]>
> Cc: Daniel Borkmann <[email protected]>
> Cc: Peter Zijlstra <[email protected]>
> Cc: [email protected]

Applied to bpf tree, thanks Mark! I've also just submitted one for
BPF progs (http://patchwork.ozlabs.org/patch/908385/) which is same
situation.

2018-05-04 10:51:15

by Mark Rutland

[permalink] [raw]
Subject: Re: [PATCH] bpf: fix possible spectre-v1 in find_and_alloc_map()

On Fri, May 04, 2018 at 02:16:31AM +0200, Daniel Borkmann wrote:
> On 05/03/2018 06:04 PM, Mark Rutland wrote:
> > It's possible for userspace to control attr->map_type. Sanitize it when
> > using it as an array index to prevent an out-of-bounds value being used
> > under speculation.
> >
> > Found by smatch.
> >
> > Signed-off-by: Mark Rutland <[email protected]>
> > Cc: Alexei Starovoitov <[email protected]>
> > Cc: Dan Carpenter <[email protected]>
> > Cc: Daniel Borkmann <[email protected]>
> > Cc: Peter Zijlstra <[email protected]>
> > Cc: [email protected]
>
> Applied to bpf tree, thanks Mark!

Cheers!

> I've also just submitted one for BPF progs
> (http://patchwork.ozlabs.org/patch/908385/) which is same situation.

That looks good to me. That case doesn't show up in my smatch results so
far, but I might just need a few more build iterations.

Thanks,
Mark.