hc
2024-09-20 cf4ce59b3b70238352c7f1729f0f7223214828ad
kernel/kernel/bpf/map_in_map.c
....@@ -1,8 +1,5 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* Copyright (c) 2017 Facebook
2
- *
3
- * This program is free software; you can redistribute it and/or
4
- * modify it under the terms of version 2 of the GNU General Public
5
- * License as published by the Free Software Foundation.
63 */
74 #include <linux/slab.h>
85 #include <linux/bpf.h>
....@@ -20,20 +17,20 @@
2017 if (IS_ERR(inner_map))
2118 return inner_map;
2219
23
- /* prog_array->owner_prog_type and owner_jited
24
- * is a runtime binding. Doing static check alone
25
- * in the verifier is not enough.
26
- */
27
- if (inner_map->map_type == BPF_MAP_TYPE_PROG_ARRAY ||
28
- inner_map->map_type == BPF_MAP_TYPE_CGROUP_STORAGE) {
29
- fdput(f);
30
- return ERR_PTR(-ENOTSUPP);
31
- }
32
-
3320 /* Does not support >1 level map-in-map */
3421 if (inner_map->inner_map_meta) {
3522 fdput(f);
3623 return ERR_PTR(-EINVAL);
24
+ }
25
+
26
+ if (!inner_map->ops->map_meta_equal) {
27
+ fdput(f);
28
+ return ERR_PTR(-ENOTSUPP);
29
+ }
30
+
31
+ if (map_value_has_spin_lock(inner_map)) {
32
+ fdput(f);
33
+ return ERR_PTR(-ENOTSUPP);
3734 }
3835
3936 inner_map_meta_size = sizeof(*inner_map_meta);
....@@ -52,11 +49,12 @@
5249 inner_map_meta->value_size = inner_map->value_size;
5350 inner_map_meta->map_flags = inner_map->map_flags;
5451 inner_map_meta->max_entries = inner_map->max_entries;
52
+ inner_map_meta->spin_lock_off = inner_map->spin_lock_off;
5553
5654 /* Misc members not needed in bpf_map_meta_equal() check. */
5755 inner_map_meta->ops = inner_map->ops;
5856 if (inner_map->ops == &array_map_ops) {
59
- inner_map_meta->unpriv_array = inner_map->unpriv_array;
57
+ inner_map_meta->bypass_spec_v1 = inner_map->bypass_spec_v1;
6058 container_of(inner_map_meta, struct bpf_array, map)->index_mask =
6159 container_of(inner_map, struct bpf_array, map)->index_mask;
6260 }
....@@ -77,15 +75,14 @@
7775 return meta0->map_type == meta1->map_type &&
7876 meta0->key_size == meta1->key_size &&
7977 meta0->value_size == meta1->value_size &&
80
- meta0->map_flags == meta1->map_flags &&
81
- meta0->max_entries == meta1->max_entries;
78
+ meta0->map_flags == meta1->map_flags;
8279 }
8380
8481 void *bpf_map_fd_get_ptr(struct bpf_map *map,
8582 struct file *map_file /* not used */,
8683 int ufd)
8784 {
88
- struct bpf_map *inner_map;
85
+ struct bpf_map *inner_map, *inner_map_meta;
8986 struct fd f;
9087
9188 f = fdget(ufd);
....@@ -93,8 +90,9 @@
9390 if (IS_ERR(inner_map))
9491 return inner_map;
9592
96
- if (bpf_map_meta_equal(map->inner_map_meta, inner_map))
97
- inner_map = bpf_map_inc(inner_map, false);
93
+ inner_map_meta = map->inner_map_meta;
94
+ if (inner_map_meta->ops->map_meta_equal(inner_map_meta, inner_map))
95
+ bpf_map_inc(inner_map);
9896 else
9997 inner_map = ERR_PTR(-EINVAL);
10098