diff options
author | Alexei Starovoitov <ast@kernel.org> | 2018-11-22 13:49:56 -0500 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2018-11-22 15:29:40 -0500 |
commit | 813961de3ee6474dd5703e883471fd941d6c8f69 (patch) | |
tree | c96784f1ab86f2fcdf98c420fd1f7fcb714e7107 /kernel/bpf/queue_stack_maps.c | |
parent | dde7011a824cfa815b03f853ec985ff46b740939 (diff) |
bpf: fix integer overflow in queue_stack_map
Fix the following issues:
- allow queue_stack_map for root only
- fix u32 max_entries overflow
- disallow value_size == 0
Fixes: f1a2e44a3aec ("bpf: add queue and stack maps")
Reported-by: Wei Wu <ww9210@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Cc: Mauricio Vasquez B <mauricio.vasquez@polito.it>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'kernel/bpf/queue_stack_maps.c')
-rw-r--r-- | kernel/bpf/queue_stack_maps.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/kernel/bpf/queue_stack_maps.c b/kernel/bpf/queue_stack_maps.c index 8bbd72d3a121..b384ea9f3254 100644 --- a/kernel/bpf/queue_stack_maps.c +++ b/kernel/bpf/queue_stack_maps.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/bpf.h> | 7 | #include <linux/bpf.h> |
8 | #include <linux/list.h> | 8 | #include <linux/list.h> |
9 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
10 | #include <linux/capability.h> | ||
10 | #include "percpu_freelist.h" | 11 | #include "percpu_freelist.h" |
11 | 12 | ||
12 | #define QUEUE_STACK_CREATE_FLAG_MASK \ | 13 | #define QUEUE_STACK_CREATE_FLAG_MASK \ |
@@ -45,8 +46,12 @@ static bool queue_stack_map_is_full(struct bpf_queue_stack *qs) | |||
45 | /* Called from syscall */ | 46 | /* Called from syscall */ |
46 | static int queue_stack_map_alloc_check(union bpf_attr *attr) | 47 | static int queue_stack_map_alloc_check(union bpf_attr *attr) |
47 | { | 48 | { |
49 | if (!capable(CAP_SYS_ADMIN)) | ||
50 | return -EPERM; | ||
51 | |||
48 | /* check sanity of attributes */ | 52 | /* check sanity of attributes */ |
49 | if (attr->max_entries == 0 || attr->key_size != 0 || | 53 | if (attr->max_entries == 0 || attr->key_size != 0 || |
54 | attr->value_size == 0 || | ||
50 | attr->map_flags & ~QUEUE_STACK_CREATE_FLAG_MASK) | 55 | attr->map_flags & ~QUEUE_STACK_CREATE_FLAG_MASK) |
51 | return -EINVAL; | 56 | return -EINVAL; |
52 | 57 | ||
@@ -63,15 +68,10 @@ static struct bpf_map *queue_stack_map_alloc(union bpf_attr *attr) | |||
63 | { | 68 | { |
64 | int ret, numa_node = bpf_map_attr_numa_node(attr); | 69 | int ret, numa_node = bpf_map_attr_numa_node(attr); |
65 | struct bpf_queue_stack *qs; | 70 | struct bpf_queue_stack *qs; |
66 | u32 size, value_size; | 71 | u64 size, queue_size, cost; |
67 | u64 queue_size, cost; | ||
68 | |||
69 | size = attr->max_entries + 1; | ||
70 | value_size = attr->value_size; | ||
71 | |||
72 | queue_size = sizeof(*qs) + (u64) value_size * size; | ||
73 | 72 | ||
74 | cost = queue_size; | 73 | size = (u64) attr->max_entries + 1; |
74 | cost = queue_size = sizeof(*qs) + size * attr->value_size; | ||
75 | if (cost >= U32_MAX - PAGE_SIZE) | 75 | if (cost >= U32_MAX - PAGE_SIZE) |
76 | return ERR_PTR(-E2BIG); | 76 | return ERR_PTR(-E2BIG); |
77 | 77 | ||