mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-01 06:33:07 +00:00
bpf: Inline map creation logic in map_create() function
[ Upstream commit22db41226b
] 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 Stable-dep-of:640a604585
("bpf, cpumap: Make sure kthread is running before map update returns") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
3cf214f275
commit
514b9c25ff
1 changed files with 24 additions and 33 deletions
|
@ -109,37 +109,6 @@ const struct bpf_map_ops bpf_map_offload_ops = {
|
||||||
.map_mem_usage = bpf_map_offload_map_mem_usage,
|
.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)
|
static void bpf_map_write_active_inc(struct bpf_map *map)
|
||||||
{
|
{
|
||||||
atomic64_inc(&map->writecnt);
|
atomic64_inc(&map->writecnt);
|
||||||
|
@ -1127,7 +1096,9 @@ static int map_check_btf(struct bpf_map *map, const struct btf *btf,
|
||||||
/* called via syscall */
|
/* called via syscall */
|
||||||
static int map_create(union bpf_attr *attr)
|
static int map_create(union bpf_attr *attr)
|
||||||
{
|
{
|
||||||
|
const struct bpf_map_ops *ops;
|
||||||
int numa_node = bpf_map_attr_numa_node(attr);
|
int numa_node = bpf_map_attr_numa_node(attr);
|
||||||
|
u32 map_type = attr->map_type;
|
||||||
struct bpf_map *map;
|
struct bpf_map *map;
|
||||||
int f_flags;
|
int f_flags;
|
||||||
int err;
|
int err;
|
||||||
|
@ -1157,6 +1128,25 @@ static int map_create(union bpf_attr *attr)
|
||||||
!node_online(numa_node)))
|
!node_online(numa_node)))
|
||||||
return -EINVAL;
|
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
|
/* Intent here is for unprivileged_bpf_disabled to block BPF map
|
||||||
* creation for unprivileged users; other actions depend
|
* creation for unprivileged users; other actions depend
|
||||||
* on fd availability and access to bpffs, so are dependent on
|
* 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())
|
if (sysctl_unprivileged_bpf_disabled && !bpf_capable())
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
/* find map type and init map: hashtable vs rbtree vs bloom vs ... */
|
map = ops->map_alloc(attr);
|
||||||
map = find_and_alloc_map(attr);
|
|
||||||
if (IS_ERR(map))
|
if (IS_ERR(map))
|
||||||
return PTR_ERR(map);
|
return PTR_ERR(map);
|
||||||
|
map->ops = ops;
|
||||||
|
map->map_type = map_type;
|
||||||
|
|
||||||
err = bpf_obj_name_cpy(map->name, attr->map_name,
|
err = bpf_obj_name_cpy(map->name, attr->map_name,
|
||||||
sizeof(attr->map_name));
|
sizeof(attr->map_name));
|
||||||
|
|
Loading…
Reference in a new issue