diff options
-rw-r--r-- | kernel/bpf/arraymap.c | 17 | ||||
-rw-r--r-- | kernel/bpf/hashtab.c | 5 |
2 files changed, 16 insertions, 6 deletions
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index 58b80c137afd..9eb4d8a7cd87 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c | |||
@@ -25,7 +25,7 @@ struct bpf_array { | |||
25 | static struct bpf_map *array_map_alloc(union bpf_attr *attr) | 25 | static struct bpf_map *array_map_alloc(union bpf_attr *attr) |
26 | { | 26 | { |
27 | struct bpf_array *array; | 27 | struct bpf_array *array; |
28 | u32 elem_size; | 28 | u32 elem_size, array_size; |
29 | 29 | ||
30 | /* check sanity of attributes */ | 30 | /* check sanity of attributes */ |
31 | if (attr->max_entries == 0 || attr->key_size != 4 || | 31 | if (attr->max_entries == 0 || attr->key_size != 4 || |
@@ -34,11 +34,17 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) | |||
34 | 34 | ||
35 | elem_size = round_up(attr->value_size, 8); | 35 | elem_size = round_up(attr->value_size, 8); |
36 | 36 | ||
37 | /* check round_up into zero and u32 overflow */ | ||
38 | if (elem_size == 0 || | ||
39 | attr->max_entries > (U32_MAX - sizeof(*array)) / elem_size) | ||
40 | return ERR_PTR(-ENOMEM); | ||
41 | |||
42 | array_size = sizeof(*array) + attr->max_entries * elem_size; | ||
43 | |||
37 | /* allocate all map elements and zero-initialize them */ | 44 | /* allocate all map elements and zero-initialize them */ |
38 | array = kzalloc(sizeof(*array) + attr->max_entries * elem_size, | 45 | array = kzalloc(array_size, GFP_USER | __GFP_NOWARN); |
39 | GFP_USER | __GFP_NOWARN); | ||
40 | if (!array) { | 46 | if (!array) { |
41 | array = vzalloc(array->map.max_entries * array->elem_size); | 47 | array = vzalloc(array_size); |
42 | if (!array) | 48 | if (!array) |
43 | return ERR_PTR(-ENOMEM); | 49 | return ERR_PTR(-ENOMEM); |
44 | } | 50 | } |
@@ -51,7 +57,6 @@ static struct bpf_map *array_map_alloc(union bpf_attr *attr) | |||
51 | array->elem_size = elem_size; | 57 | array->elem_size = elem_size; |
52 | 58 | ||
53 | return &array->map; | 59 | return &array->map; |
54 | |||
55 | } | 60 | } |
56 | 61 | ||
57 | /* Called from syscall or from eBPF program */ | 62 | /* Called from syscall or from eBPF program */ |
@@ -101,7 +106,7 @@ static int array_map_update_elem(struct bpf_map *map, void *key, void *value, | |||
101 | return -E2BIG; | 106 | return -E2BIG; |
102 | 107 | ||
103 | if (map_flags == BPF_NOEXIST) | 108 | if (map_flags == BPF_NOEXIST) |
104 | /* all elemenets already exist */ | 109 | /* all elements already exist */ |
105 | return -EEXIST; | 110 | return -EEXIST; |
106 | 111 | ||
107 | memcpy(array->value + array->elem_size * index, value, array->elem_size); | 112 | memcpy(array->value + array->elem_size * index, value, array->elem_size); |
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index d234a012f046..b3ba43674310 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c | |||
@@ -65,6 +65,11 @@ static struct bpf_map *htab_map_alloc(union bpf_attr *attr) | |||
65 | goto free_htab; | 65 | goto free_htab; |
66 | 66 | ||
67 | err = -ENOMEM; | 67 | err = -ENOMEM; |
68 | /* prevent zero size kmalloc and check for u32 overflow */ | ||
69 | if (htab->n_buckets == 0 || | ||
70 | htab->n_buckets > U32_MAX / sizeof(struct hlist_head)) | ||
71 | goto free_htab; | ||
72 | |||
68 | htab->buckets = kmalloc_array(htab->n_buckets, sizeof(struct hlist_head), | 73 | htab->buckets = kmalloc_array(htab->n_buckets, sizeof(struct hlist_head), |
69 | GFP_USER | __GFP_NOWARN); | 74 | GFP_USER | __GFP_NOWARN); |
70 | 75 | ||