Skip to content

Commit 960c947

Browse files
borkmanngregkh
authored andcommitted
bpf: Move bpf map owner out of common struct
[ Upstream commit fd1c98f ] Given this is only relevant for BPF tail call maps, it is adding up space and penalizing other map types. We also need to extend this with further objects to track / compare to. Therefore, lets move this out into a separate structure and dynamically allocate it only for BPF tail call maps. Signed-off-by: Daniel Borkmann <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]> Stable-dep-of: abad3d0 ("bpf: Fix oob access in cgroup local storage") Signed-off-by: Sasha Levin <[email protected]>
1 parent e5f141e commit 960c947

File tree

3 files changed

+49
-35
lines changed

3 files changed

+49
-35
lines changed

include/linux/bpf.h

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,18 @@ struct bpf_list_node_kern {
260260
void *owner;
261261
} __attribute__((aligned(8)));
262262

263+
/* 'Ownership' of program-containing map is claimed by the first program
264+
* that is going to use this map or by the first program which FD is
265+
* stored in the map to make sure that all callers and callees have the
266+
* same prog type, JITed flag and xdp_has_frags flag.
267+
*/
268+
struct bpf_map_owner {
269+
enum bpf_prog_type type;
270+
bool jited;
271+
bool xdp_has_frags;
272+
const struct btf_type *attach_func_proto;
273+
};
274+
263275
struct bpf_map {
264276
const struct bpf_map_ops *ops;
265277
struct bpf_map *inner_map_meta;
@@ -292,18 +304,8 @@ struct bpf_map {
292304
struct rcu_head rcu;
293305
};
294306
atomic64_t writecnt;
295-
/* 'Ownership' of program-containing map is claimed by the first program
296-
* that is going to use this map or by the first program which FD is
297-
* stored in the map to make sure that all callers and callees have the
298-
* same prog type, JITed flag and xdp_has_frags flag.
299-
*/
300-
struct {
301-
const struct btf_type *attach_func_proto;
302-
spinlock_t lock;
303-
enum bpf_prog_type type;
304-
bool jited;
305-
bool xdp_has_frags;
306-
} owner;
307+
spinlock_t owner_lock;
308+
struct bpf_map_owner *owner;
307309
bool bypass_spec_v1;
308310
bool frozen; /* write-once; write-protected by freeze_mutex */
309311
bool free_after_mult_rcu_gp;
@@ -2072,6 +2074,16 @@ static inline bool bpf_map_flags_access_ok(u32 access_flags)
20722074
(BPF_F_RDONLY_PROG | BPF_F_WRONLY_PROG);
20732075
}
20742076

2077+
static inline struct bpf_map_owner *bpf_map_owner_alloc(struct bpf_map *map)
2078+
{
2079+
return kzalloc(sizeof(*map->owner), GFP_ATOMIC);
2080+
}
2081+
2082+
static inline void bpf_map_owner_free(struct bpf_map *map)
2083+
{
2084+
kfree(map->owner);
2085+
}
2086+
20752087
struct bpf_event_entry {
20762088
struct perf_event *event;
20772089
struct file *perf_file;

kernel/bpf/core.c

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2365,28 +2365,29 @@ static bool __bpf_prog_map_compatible(struct bpf_map *map,
23652365
const struct bpf_prog *fp)
23662366
{
23672367
enum bpf_prog_type prog_type = resolve_prog_type(fp);
2368-
bool ret;
23692368
struct bpf_prog_aux *aux = fp->aux;
2369+
bool ret = false;
23702370

23712371
if (fp->kprobe_override)
2372-
return false;
2372+
return ret;
23732373

2374-
spin_lock(&map->owner.lock);
2375-
if (!map->owner.type) {
2376-
/* There's no owner yet where we could check for
2377-
* compatibility.
2378-
*/
2379-
map->owner.type = prog_type;
2380-
map->owner.jited = fp->jited;
2381-
map->owner.xdp_has_frags = aux->xdp_has_frags;
2382-
map->owner.attach_func_proto = aux->attach_func_proto;
2374+
spin_lock(&map->owner_lock);
2375+
/* There's no owner yet where we could check for compatibility. */
2376+
if (!map->owner) {
2377+
map->owner = bpf_map_owner_alloc(map);
2378+
if (!map->owner)
2379+
goto err;
2380+
map->owner->type = prog_type;
2381+
map->owner->jited = fp->jited;
2382+
map->owner->xdp_has_frags = aux->xdp_has_frags;
2383+
map->owner->attach_func_proto = aux->attach_func_proto;
23832384
ret = true;
23842385
} else {
2385-
ret = map->owner.type == prog_type &&
2386-
map->owner.jited == fp->jited &&
2387-
map->owner.xdp_has_frags == aux->xdp_has_frags;
2386+
ret = map->owner->type == prog_type &&
2387+
map->owner->jited == fp->jited &&
2388+
map->owner->xdp_has_frags == aux->xdp_has_frags;
23882389
if (ret &&
2389-
map->owner.attach_func_proto != aux->attach_func_proto) {
2390+
map->owner->attach_func_proto != aux->attach_func_proto) {
23902391
switch (prog_type) {
23912392
case BPF_PROG_TYPE_TRACING:
23922393
case BPF_PROG_TYPE_LSM:
@@ -2399,8 +2400,8 @@ static bool __bpf_prog_map_compatible(struct bpf_map *map,
23992400
}
24002401
}
24012402
}
2402-
spin_unlock(&map->owner.lock);
2403-
2403+
err:
2404+
spin_unlock(&map->owner_lock);
24042405
return ret;
24052406
}
24062407

kernel/bpf/syscall.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,7 @@ static void bpf_map_free_deferred(struct work_struct *work)
887887

888888
security_bpf_map_free(map);
889889
bpf_map_release_memcg(map);
890+
bpf_map_owner_free(map);
890891
bpf_map_free(map);
891892
}
892893

@@ -981,12 +982,12 @@ static void bpf_map_show_fdinfo(struct seq_file *m, struct file *filp)
981982
struct bpf_map *map = filp->private_data;
982983
u32 type = 0, jited = 0;
983984

984-
if (map_type_contains_progs(map)) {
985-
spin_lock(&map->owner.lock);
986-
type = map->owner.type;
987-
jited = map->owner.jited;
988-
spin_unlock(&map->owner.lock);
985+
spin_lock(&map->owner_lock);
986+
if (map->owner) {
987+
type = map->owner->type;
988+
jited = map->owner->jited;
989989
}
990+
spin_unlock(&map->owner_lock);
990991

991992
seq_printf(m,
992993
"map_type:\t%u\n"
@@ -1496,7 +1497,7 @@ static int map_create(union bpf_attr *attr, bool kernel)
14961497
atomic64_set(&map->refcnt, 1);
14971498
atomic64_set(&map->usercnt, 1);
14981499
mutex_init(&map->freeze_mutex);
1499-
spin_lock_init(&map->owner.lock);
1500+
spin_lock_init(&map->owner_lock);
15001501

15011502
if (attr->btf_key_type_id || attr->btf_value_type_id ||
15021503
/* Even the map's value is a kernel's struct,

0 commit comments

Comments
 (0)