Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad46061f authored by Jakub Kicinski's avatar Jakub Kicinski Committed by Daniel Borkmann
Browse files

bpf: arraymap: move checks out of alloc function



Use the new callback to perform allocation checks for array maps.
The fd maps don't need a special allocation callback, they only
need a special check callback.

Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarQuentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent 0c91c423
Loading
Loading
Loading
Loading
+28 −14
Original line number Diff line number Diff line
@@ -49,27 +49,35 @@ static int bpf_array_alloc_percpu(struct bpf_array *array)
}

/* Called from syscall */
static struct bpf_map *array_map_alloc(union bpf_attr *attr)
static int array_map_alloc_check(union bpf_attr *attr)
{
	bool percpu = attr->map_type == BPF_MAP_TYPE_PERCPU_ARRAY;
	int numa_node = bpf_map_attr_numa_node(attr);
	u32 elem_size, index_mask, max_entries;
	bool unpriv = !capable(CAP_SYS_ADMIN);
	struct bpf_array *array;
	u64 array_size, mask64;

	/* check sanity of attributes */
	if (attr->max_entries == 0 || attr->key_size != 4 ||
	    attr->value_size == 0 ||
	    attr->map_flags & ~ARRAY_CREATE_FLAG_MASK ||
	    (percpu && numa_node != NUMA_NO_NODE))
		return ERR_PTR(-EINVAL);
		return -EINVAL;

	if (attr->value_size > KMALLOC_MAX_SIZE)
		/* if value_size is bigger, the user space won't be able to
		 * access the elements.
		 */
		return ERR_PTR(-E2BIG);
		return -E2BIG;

	return 0;
}

static struct bpf_map *array_map_alloc(union bpf_attr *attr)
{
	bool percpu = attr->map_type == BPF_MAP_TYPE_PERCPU_ARRAY;
	int numa_node = bpf_map_attr_numa_node(attr);
	u32 elem_size, index_mask, max_entries;
	bool unpriv = !capable(CAP_SYS_ADMIN);
	struct bpf_array *array;
	u64 array_size, mask64;

	elem_size = round_up(attr->value_size, 8);

@@ -327,6 +335,7 @@ static void array_map_free(struct bpf_map *map)
}

const struct bpf_map_ops array_map_ops = {
	.map_alloc_check = array_map_alloc_check,
	.map_alloc = array_map_alloc,
	.map_free = array_map_free,
	.map_get_next_key = array_map_get_next_key,
@@ -337,6 +346,7 @@ const struct bpf_map_ops array_map_ops = {
};

const struct bpf_map_ops percpu_array_map_ops = {
	.map_alloc_check = array_map_alloc_check,
	.map_alloc = array_map_alloc,
	.map_free = array_map_free,
	.map_get_next_key = array_map_get_next_key,
@@ -345,12 +355,12 @@ const struct bpf_map_ops percpu_array_map_ops = {
	.map_delete_elem = array_map_delete_elem,
};

static struct bpf_map *fd_array_map_alloc(union bpf_attr *attr)
static int fd_array_map_alloc_check(union bpf_attr *attr)
{
	/* only file descriptors can be stored in this type of map */
	if (attr->value_size != sizeof(u32))
		return ERR_PTR(-EINVAL);
	return array_map_alloc(attr);
		return -EINVAL;
	return array_map_alloc_check(attr);
}

static void fd_array_map_free(struct bpf_map *map)
@@ -474,7 +484,8 @@ void bpf_fd_array_map_clear(struct bpf_map *map)
}

const struct bpf_map_ops prog_array_map_ops = {
	.map_alloc = fd_array_map_alloc,
	.map_alloc_check = fd_array_map_alloc_check,
	.map_alloc = array_map_alloc,
	.map_free = fd_array_map_free,
	.map_get_next_key = array_map_get_next_key,
	.map_lookup_elem = fd_array_map_lookup_elem,
@@ -561,7 +572,8 @@ static void perf_event_fd_array_release(struct bpf_map *map,
}

const struct bpf_map_ops perf_event_array_map_ops = {
	.map_alloc = fd_array_map_alloc,
	.map_alloc_check = fd_array_map_alloc_check,
	.map_alloc = array_map_alloc,
	.map_free = fd_array_map_free,
	.map_get_next_key = array_map_get_next_key,
	.map_lookup_elem = fd_array_map_lookup_elem,
@@ -592,7 +604,8 @@ static void cgroup_fd_array_free(struct bpf_map *map)
}

const struct bpf_map_ops cgroup_array_map_ops = {
	.map_alloc = fd_array_map_alloc,
	.map_alloc_check = fd_array_map_alloc_check,
	.map_alloc = array_map_alloc,
	.map_free = cgroup_fd_array_free,
	.map_get_next_key = array_map_get_next_key,
	.map_lookup_elem = fd_array_map_lookup_elem,
@@ -610,7 +623,7 @@ static struct bpf_map *array_of_map_alloc(union bpf_attr *attr)
	if (IS_ERR(inner_map_meta))
		return inner_map_meta;

	map = fd_array_map_alloc(attr);
	map = array_map_alloc(attr);
	if (IS_ERR(map)) {
		bpf_map_meta_free(inner_map_meta);
		return map;
@@ -673,6 +686,7 @@ static u32 array_of_map_gen_lookup(struct bpf_map *map,
}

const struct bpf_map_ops array_of_maps_map_ops = {
	.map_alloc_check = fd_array_map_alloc_check,
	.map_alloc = array_of_map_alloc,
	.map_free = array_of_map_free,
	.map_get_next_key = array_map_get_next_key,