Message ID | 20180503160459.4111-1-mark.rutland@arm.com |
---|---|
State | Accepted |
Commit | 9ef09e35e521bf0df5325cc9cffa726a8f5f3c1b |
Headers | show |
Series | bpf: fix possible spectre-v1 in find_and_alloc_map() | expand |
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 <mark.rutland@arm.com> > Cc: Alexei Starovoitov <ast@kernel.org> > Cc: Dan Carpenter <dan.carpenter@oracle.com> > Cc: Daniel Borkmann <daniel@iogearbox.net> > Cc: Peter Zijlstra <peterz@infradead.org> > Cc: netdev@vger.kernel.org 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.
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 <mark.rutland@arm.com> > > Cc: Alexei Starovoitov <ast@kernel.org> > > Cc: Dan Carpenter <dan.carpenter@oracle.com> > > Cc: Daniel Borkmann <daniel@iogearbox.net> > > Cc: Peter Zijlstra <peterz@infradead.org> > > Cc: netdev@vger.kernel.org > > 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.
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; }
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 <mark.rutland@arm.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Dan Carpenter <dan.carpenter@oracle.com> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: Peter Zijlstra <peterz@infradead.org> Cc: netdev@vger.kernel.org --- 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. -- 2.11.0