diff options
Diffstat (limited to 'kernel/bpf/map_in_map.c')
| -rw-r--r-- | kernel/bpf/map_in_map.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/kernel/bpf/map_in_map.c b/kernel/bpf/map_in_map.c index 99d243e1ad6e..52378d3e34b3 100644 --- a/kernel/bpf/map_in_map.c +++ b/kernel/bpf/map_in_map.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd) | 12 | struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd) |
| 13 | { | 13 | { |
| 14 | struct bpf_map *inner_map, *inner_map_meta; | 14 | struct bpf_map *inner_map, *inner_map_meta; |
| 15 | u32 inner_map_meta_size; | ||
| 15 | struct fd f; | 16 | struct fd f; |
| 16 | 17 | ||
| 17 | f = fdget(inner_map_ufd); | 18 | f = fdget(inner_map_ufd); |
| @@ -36,7 +37,12 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd) | |||
| 36 | return ERR_PTR(-EINVAL); | 37 | return ERR_PTR(-EINVAL); |
| 37 | } | 38 | } |
| 38 | 39 | ||
| 39 | inner_map_meta = kzalloc(sizeof(*inner_map_meta), GFP_USER); | 40 | inner_map_meta_size = sizeof(*inner_map_meta); |
| 41 | /* In some cases verifier needs to access beyond just base map. */ | ||
| 42 | if (inner_map->ops == &array_map_ops) | ||
| 43 | inner_map_meta_size = sizeof(struct bpf_array); | ||
| 44 | |||
| 45 | inner_map_meta = kzalloc(inner_map_meta_size, GFP_USER); | ||
| 40 | if (!inner_map_meta) { | 46 | if (!inner_map_meta) { |
| 41 | fdput(f); | 47 | fdput(f); |
| 42 | return ERR_PTR(-ENOMEM); | 48 | return ERR_PTR(-ENOMEM); |
| @@ -46,9 +52,16 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd) | |||
| 46 | inner_map_meta->key_size = inner_map->key_size; | 52 | inner_map_meta->key_size = inner_map->key_size; |
| 47 | inner_map_meta->value_size = inner_map->value_size; | 53 | inner_map_meta->value_size = inner_map->value_size; |
| 48 | inner_map_meta->map_flags = inner_map->map_flags; | 54 | inner_map_meta->map_flags = inner_map->map_flags; |
| 49 | inner_map_meta->ops = inner_map->ops; | ||
| 50 | inner_map_meta->max_entries = inner_map->max_entries; | 55 | inner_map_meta->max_entries = inner_map->max_entries; |
| 51 | 56 | ||
| 57 | /* Misc members not needed in bpf_map_meta_equal() check. */ | ||
| 58 | inner_map_meta->ops = inner_map->ops; | ||
| 59 | if (inner_map->ops == &array_map_ops) { | ||
| 60 | inner_map_meta->unpriv_array = inner_map->unpriv_array; | ||
| 61 | container_of(inner_map_meta, struct bpf_array, map)->index_mask = | ||
| 62 | container_of(inner_map, struct bpf_array, map)->index_mask; | ||
| 63 | } | ||
| 64 | |||
| 52 | fdput(f); | 65 | fdput(f); |
| 53 | return inner_map_meta; | 66 | return inner_map_meta; |
| 54 | } | 67 | } |
