Skip to content

Commit 5fd79ed

Browse files
author
Alexei Starovoitov
committed
Merge branch 'Fix leaks in libbpf and selftests'
Andrii Nakryiko says: ==================== Fix all the memory leaks reported by ASAN. All but one are just improper resource clean up in selftests. But one memory leak was discovered in libbpf, leaving inner map's name leaked. First patch fixes selftests' Makefile by passing through SAN_CFLAGS to linker. Without that compiling with SAN_CFLAGS=-fsanitize=address kept failing. Running selftests under ASAN in BPF CI is the next step, we just need to make sure all the necessary libraries (libasan and liblsan) are installed on the host and inside the VM. Would be great to get some help with that, but for now make sure that test_progs run is clean from leak sanitizer errors. v3->v4: - rebase on latest bpf-next; v2->v3: - fix per-cpu array memory leaks in btf_iter.c selftests (Hengqi); v1->v2: - call bpf_map__destroy() conditionally if map->inner_map is present. ==================== Signed-off-by: Alexei Starovoitov <[email protected]>
2 parents 5577f24 + 8c7a955 commit 5fd79ed

File tree

9 files changed

+29
-16
lines changed

9 files changed

+29
-16
lines changed

tools/lib/bpf/libbpf.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -9009,7 +9009,10 @@ int bpf_map__set_inner_map_fd(struct bpf_map *map, int fd)
90099009
pr_warn("error: inner_map_fd already specified\n");
90109010
return libbpf_err(-EINVAL);
90119011
}
9012-
zfree(&map->inner_map);
9012+
if (map->inner_map) {
9013+
bpf_map__destroy(map->inner_map);
9014+
zfree(&map->inner_map);
9015+
}
90139016
map->inner_map_fd = fd;
90149017
return 0;
90159018
}

tools/testing/selftests/bpf/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ SAN_CFLAGS ?=
2424
CFLAGS += -g -O0 -rdynamic -Wall $(GENFLAGS) $(SAN_CFLAGS) \
2525
-I$(CURDIR) -I$(INCLUDE_DIR) -I$(GENDIR) -I$(LIBDIR) \
2626
-I$(TOOLSINCDIR) -I$(APIDIR) -I$(OUTPUT)
27+
LDFLAGS += $(SAN_CFLAGS)
2728
LDLIBS += -lcap -lelf -lz -lrt -lpthread
2829

2930
# Silence some warnings when compiled with clang

tools/testing/selftests/bpf/btf_helpers.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -251,18 +251,23 @@ const char *btf_type_c_dump(const struct btf *btf)
251251
d = btf_dump__new(btf, NULL, &opts, btf_dump_printf);
252252
if (libbpf_get_error(d)) {
253253
fprintf(stderr, "Failed to create btf_dump instance: %ld\n", libbpf_get_error(d));
254-
return NULL;
254+
goto err_out;
255255
}
256256

257257
for (i = 1; i < btf__type_cnt(btf); i++) {
258258
err = btf_dump__dump_type(d, i);
259259
if (err) {
260260
fprintf(stderr, "Failed to dump type [%d]: %d\n", i, err);
261-
return NULL;
261+
goto err_out;
262262
}
263263
}
264264

265+
btf_dump__free(d);
265266
fflush(buf_file);
266267
fclose(buf_file);
267268
return buf;
269+
err_out:
270+
btf_dump__free(d);
271+
fclose(buf_file);
272+
return NULL;
268273
}

tools/testing/selftests/bpf/prog_tests/bpf_iter.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -699,14 +699,13 @@ static void test_bpf_percpu_hash_map(void)
699699
char buf[64];
700700
void *val;
701701

702-
val = malloc(8 * bpf_num_possible_cpus());
703-
704702
skel = bpf_iter_bpf_percpu_hash_map__open();
705703
if (CHECK(!skel, "bpf_iter_bpf_percpu_hash_map__open",
706704
"skeleton open failed\n"))
707705
return;
708706

709707
skel->rodata->num_cpus = bpf_num_possible_cpus();
708+
val = malloc(8 * bpf_num_possible_cpus());
710709

711710
err = bpf_iter_bpf_percpu_hash_map__load(skel);
712711
if (CHECK(!skel, "bpf_iter_bpf_percpu_hash_map__load",
@@ -770,6 +769,7 @@ static void test_bpf_percpu_hash_map(void)
770769
bpf_link__destroy(link);
771770
out:
772771
bpf_iter_bpf_percpu_hash_map__destroy(skel);
772+
free(val);
773773
}
774774

775775
static void test_bpf_array_map(void)
@@ -870,14 +870,13 @@ static void test_bpf_percpu_array_map(void)
870870
void *val;
871871
int len;
872872

873-
val = malloc(8 * bpf_num_possible_cpus());
874-
875873
skel = bpf_iter_bpf_percpu_array_map__open();
876874
if (CHECK(!skel, "bpf_iter_bpf_percpu_array_map__open",
877875
"skeleton open failed\n"))
878876
return;
879877

880878
skel->rodata->num_cpus = bpf_num_possible_cpus();
879+
val = malloc(8 * bpf_num_possible_cpus());
881880

882881
err = bpf_iter_bpf_percpu_array_map__load(skel);
883882
if (CHECK(!skel, "bpf_iter_bpf_percpu_array_map__load",
@@ -933,6 +932,7 @@ static void test_bpf_percpu_array_map(void)
933932
bpf_link__destroy(link);
934933
out:
935934
bpf_iter_bpf_percpu_array_map__destroy(skel);
935+
free(val);
936936
}
937937

938938
/* An iterator program deletes all local storage in a map. */

tools/testing/selftests/bpf/prog_tests/btf.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -4046,11 +4046,9 @@ static void *btf_raw_create(const struct btf_header *hdr,
40464046
next_str_idx < strs_cnt ? strs_idx[next_str_idx] : NULL;
40474047

40484048
done:
4049+
free(strs_idx);
40494050
if (err) {
4050-
if (raw_btf)
4051-
free(raw_btf);
4052-
if (strs_idx)
4053-
free(strs_idx);
4051+
free(raw_btf);
40544052
return NULL;
40554053
}
40564054
return raw_btf;

tools/testing/selftests/bpf/prog_tests/btf_dump.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -814,21 +814,25 @@ static void test_btf_datasec(struct btf *btf, struct btf_dump *d, char *str,
814814

815815
static void test_btf_dump_datasec_data(char *str)
816816
{
817-
struct btf *btf = btf__parse("xdping_kern.o", NULL);
817+
struct btf *btf;
818818
struct btf_dump_opts opts = { .ctx = str };
819819
char license[4] = "GPL";
820820
struct btf_dump *d;
821821

822+
btf = btf__parse("xdping_kern.o", NULL);
822823
if (!ASSERT_OK_PTR(btf, "xdping_kern.o BTF not found"))
823824
return;
824825

825826
d = btf_dump__new(btf, NULL, &opts, btf_dump_snprintf);
826827
if (!ASSERT_OK_PTR(d, "could not create BTF dump"))
827-
return;
828+
goto out;
828829

829830
test_btf_datasec(btf, d, str, "license",
830831
"SEC(\"license\") char[4] _license = (char[4])['G','P','L',];",
831832
license, sizeof(license));
833+
out:
834+
btf_dump__free(d);
835+
btf__free(btf);
832836
}
833837

834838
void test_btf_dump() {

tools/testing/selftests/bpf/prog_tests/core_reloc.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ static int setup_type_id_case_local(struct core_reloc_test_case *test)
433433

434434
static int setup_type_id_case_success(struct core_reloc_test_case *test) {
435435
struct core_reloc_type_id_output *exp = (void *)test->output;
436-
struct btf *targ_btf = btf__parse(test->btf_src_file, NULL);
436+
struct btf *targ_btf;
437437
int err;
438438

439439
err = setup_type_id_case_local(test);

tools/testing/selftests/bpf/prog_tests/migrate_reuseport.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ static int pass_ack(struct migrate_reuseport_test_case *test_case)
204204
{
205205
int err;
206206

207-
err = bpf_link__detach(test_case->link);
208-
if (!ASSERT_OK(err, "bpf_link__detach"))
207+
err = bpf_link__destroy(test_case->link);
208+
if (!ASSERT_OK(err, "bpf_link__destroy"))
209209
return -1;
210210

211211
test_case->link = NULL;

tools/testing/selftests/bpf/prog_tests/skb_ctx.c

+2
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,6 @@ void test_skb_ctx(void)
111111
"ctx_out_mark",
112112
"skb->mark == %u, expected %d\n",
113113
skb.mark, 10);
114+
115+
bpf_object__close(obj);
114116
}

0 commit comments

Comments
 (0)