Skip to content

Commit 87e9675

Browse files
Hou TaoAlexei Starovoitov
authored andcommitted
bpf: Call the missed btf_record_free() when map creation fails
When security_bpf_map_create() in map_create() fails, map_create() will call btf_put() and ->map_free() callback to free the map. It doesn't free the btf_record of map value, so add the missed btf_record_free() when map creation fails. However btf_record_free() needs to be called after ->map_free() just like bpf_map_free_deferred() did, because ->map_free() may use the btf_record to free the special fields in preallocated map value. So factor out bpf_map_free() helper to free the map, btf_record, and btf orderly and use the helper in both map_create() and bpf_map_free_deferred(). Signed-off-by: Hou Tao <[email protected]> Acked-by: Jiri Olsa <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 211bf9c commit 87e9675

File tree

1 file changed

+12
-7
lines changed

1 file changed

+12
-7
lines changed

kernel/bpf/syscall.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -735,15 +735,11 @@ void bpf_obj_free_fields(const struct btf_record *rec, void *obj)
735735
}
736736
}
737737

738-
/* called from workqueue */
739-
static void bpf_map_free_deferred(struct work_struct *work)
738+
static void bpf_map_free(struct bpf_map *map)
740739
{
741-
struct bpf_map *map = container_of(work, struct bpf_map, work);
742740
struct btf_record *rec = map->record;
743741
struct btf *btf = map->btf;
744742

745-
security_bpf_map_free(map);
746-
bpf_map_release_memcg(map);
747743
/* implementation dependent freeing */
748744
map->ops->map_free(map);
749745
/* Delay freeing of btf_record for maps, as map_free
@@ -762,6 +758,16 @@ static void bpf_map_free_deferred(struct work_struct *work)
762758
btf_put(btf);
763759
}
764760

761+
/* called from workqueue */
762+
static void bpf_map_free_deferred(struct work_struct *work)
763+
{
764+
struct bpf_map *map = container_of(work, struct bpf_map, work);
765+
766+
security_bpf_map_free(map);
767+
bpf_map_release_memcg(map);
768+
bpf_map_free(map);
769+
}
770+
765771
static void bpf_map_put_uref(struct bpf_map *map)
766772
{
767773
if (atomic64_dec_and_test(&map->usercnt)) {
@@ -1413,8 +1419,7 @@ static int map_create(union bpf_attr *attr)
14131419
free_map_sec:
14141420
security_bpf_map_free(map);
14151421
free_map:
1416-
btf_put(map->btf);
1417-
map->ops->map_free(map);
1422+
bpf_map_free(map);
14181423
put_token:
14191424
bpf_token_put(token);
14201425
return err;

0 commit comments

Comments
 (0)