]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: Inline map creation logic in map_create() function
authorAndrii Nakryiko <andrii@kernel.org>
Tue, 13 Jun 2023 22:35:31 +0000 (15:35 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Mon, 19 Jun 2023 12:04:04 +0000 (14:04 +0200)
Currently find_and_alloc_map() performs two separate functions: some
argument sanity checking and partial map creation workflow hanling.
Neither of those functions are self-sufficient and are augmented by
further checks and initialization logic in the caller (map_create()
function). So unify all the sanity checks, permission checks, and
creation and initialization logic in one linear piece of code in
map_create() instead. This also make it easier to further enhance
permission checks and keep them located in one place.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Stanislav Fomichev <sdf@google.com>
Link: https://lore.kernel.org/bpf/20230613223533.3689589-3-andrii@kernel.org
kernel/bpf/syscall.c

index 7c41a623f405cbc46dfd444093aa09cd22f890c4..6ef302709ab03f0618b6ac25f49e26b0f68d11ff 100644 (file)
@@ -109,37 +109,6 @@ const struct bpf_map_ops bpf_map_offload_ops = {
        .map_mem_usage = bpf_map_offload_map_mem_usage,
 };
 
-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 (type >= ARRAY_SIZE(bpf_map_types))
-               return ERR_PTR(-EINVAL);
-       type = array_index_nospec(type, ARRAY_SIZE(bpf_map_types));
-       ops = bpf_map_types[type];
-       if (!ops)
-               return ERR_PTR(-EINVAL);
-
-       if (ops->map_alloc_check) {
-               err = ops->map_alloc_check(attr);
-               if (err)
-                       return ERR_PTR(err);
-       }
-       if (attr->map_ifindex)
-               ops = &bpf_map_offload_ops;
-       if (!ops->map_mem_usage)
-               return ERR_PTR(-EINVAL);
-       map = ops->map_alloc(attr);
-       if (IS_ERR(map))
-               return map;
-       map->ops = ops;
-       map->map_type = type;
-       return map;
-}
-
 static void bpf_map_write_active_inc(struct bpf_map *map)
 {
        atomic64_inc(&map->writecnt);
@@ -1127,7 +1096,9 @@ free_map_tab:
 /* called via syscall */
 static int map_create(union bpf_attr *attr)
 {
+       const struct bpf_map_ops *ops;
        int numa_node = bpf_map_attr_numa_node(attr);
+       u32 map_type = attr->map_type;
        struct bpf_map *map;
        int f_flags;
        int err;
@@ -1157,6 +1128,25 @@ static int map_create(union bpf_attr *attr)
             !node_online(numa_node)))
                return -EINVAL;
 
+       /* find map type and init map: hashtable vs rbtree vs bloom vs ... */
+       map_type = attr->map_type;
+       if (map_type >= ARRAY_SIZE(bpf_map_types))
+               return -EINVAL;
+       map_type = array_index_nospec(map_type, ARRAY_SIZE(bpf_map_types));
+       ops = bpf_map_types[map_type];
+       if (!ops)
+               return -EINVAL;
+
+       if (ops->map_alloc_check) {
+               err = ops->map_alloc_check(attr);
+               if (err)
+                       return err;
+       }
+       if (attr->map_ifindex)
+               ops = &bpf_map_offload_ops;
+       if (!ops->map_mem_usage)
+               return -EINVAL;
+
        /* Intent here is for unprivileged_bpf_disabled to block BPF map
         * creation for unprivileged users; other actions depend
         * on fd availability and access to bpffs, so are dependent on
@@ -1166,10 +1156,11 @@ static int map_create(union bpf_attr *attr)
        if (sysctl_unprivileged_bpf_disabled && !bpf_capable())
                return -EPERM;
 
-       /* find map type and init map: hashtable vs rbtree vs bloom vs ... */
-       map = find_and_alloc_map(attr);
+       map = ops->map_alloc(attr);
        if (IS_ERR(map))
                return PTR_ERR(map);
+       map->ops = ops;
+       map->map_type = map_type;
 
        err = bpf_obj_name_cpy(map->name, attr->map_name,
                               sizeof(attr->map_name));