summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@kernel.org>2024-09-13 16:51:08 -0700
committerAlexei Starovoitov <ast@kernel.org>2024-09-13 16:51:21 -0700
commitca7a5bac4528f45efbc19401c926f4cbed291c95 (patch)
treefdc8947b1da054ae106965185c1506309172d4ff
parent211bf9cf178a986f025b65cee11012d4e3d6b1f8 (diff)
parent986deb297d48ae7039ab975f00c14f0bfe069125 (diff)
Merge branch 'two-tiny-fixes-for-btf-record'
Hou Tao says: ==================== The tiny patch set aims to fix two problems found during the development of supporting dynptr key in hash table. Patch #1 fixes the missed btf_record_free() when map creation fails and patch #2 fixes the missed kfree() when there is no special field in the passed btf. ==================== Link: https://lore.kernel.org/r/20240912012845.3458483-1-houtao@huaweicloud.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-rw-r--r--kernel/bpf/btf.c4
-rw-r--r--kernel/bpf/syscall.c19
2 files changed, 15 insertions, 8 deletions
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 59b4f7265761..31eae516f701 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -5572,8 +5572,10 @@ btf_parse_struct_metas(struct bpf_verifier_log *log, struct btf *btf)
aof->ids[aof->cnt++] = i;
}
- if (!aof->cnt)
+ if (!aof->cnt) {
+ kfree(aof);
return NULL;
+ }
sort(&aof->ids, aof->cnt, sizeof(aof->ids[0]), btf_id_cmp_func, NULL);
for (i = 1; i < n; i++) {
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 593822d3d393..8a4117f6d761 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -735,15 +735,11 @@ void bpf_obj_free_fields(const struct btf_record *rec, void *obj)
}
}
-/* called from workqueue */
-static void bpf_map_free_deferred(struct work_struct *work)
+static void bpf_map_free(struct bpf_map *map)
{
- struct bpf_map *map = container_of(work, struct bpf_map, work);
struct btf_record *rec = map->record;
struct btf *btf = map->btf;
- security_bpf_map_free(map);
- bpf_map_release_memcg(map);
/* implementation dependent freeing */
map->ops->map_free(map);
/* Delay freeing of btf_record for maps, as map_free
@@ -762,6 +758,16 @@ static void bpf_map_free_deferred(struct work_struct *work)
btf_put(btf);
}
+/* called from workqueue */
+static void bpf_map_free_deferred(struct work_struct *work)
+{
+ struct bpf_map *map = container_of(work, struct bpf_map, work);
+
+ security_bpf_map_free(map);
+ bpf_map_release_memcg(map);
+ bpf_map_free(map);
+}
+
static void bpf_map_put_uref(struct bpf_map *map)
{
if (atomic64_dec_and_test(&map->usercnt)) {
@@ -1413,8 +1419,7 @@ static int map_create(union bpf_attr *attr)
free_map_sec:
security_bpf_map_free(map);
free_map:
- btf_put(map->btf);
- map->ops->map_free(map);
+ bpf_map_free(map);
put_token:
bpf_token_put(token);
return err;