Commit 5fd79ed9 authored by Alexei Starovoitov's avatar Alexei Starovoitov
Browse files

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: default avatarAlexei Starovoitov <ast@kernel.org>
parents 5577f24c 8c7a9552
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -9009,7 +9009,10 @@ int bpf_map__set_inner_map_fd(struct bpf_map *map, int fd)
		pr_warn("error: inner_map_fd already specified\n");
		return libbpf_err(-EINVAL);
	}
	if (map->inner_map) {
		bpf_map__destroy(map->inner_map);
		zfree(&map->inner_map);
	}
	map->inner_map_fd = fd;
	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ SAN_CFLAGS ?=
CFLAGS += -g -O0 -rdynamic -Wall $(GENFLAGS) $(SAN_CFLAGS)		\
	  -I$(CURDIR) -I$(INCLUDE_DIR) -I$(GENDIR) -I$(LIBDIR)		\
	  -I$(TOOLSINCDIR) -I$(APIDIR) -I$(OUTPUT)
LDFLAGS += $(SAN_CFLAGS)
LDLIBS += -lcap -lelf -lz -lrt -lpthread

# Silence some warnings when compiled with clang
+7 −2
Original line number Diff line number Diff line
@@ -251,18 +251,23 @@ const char *btf_type_c_dump(const struct btf *btf)
	d = btf_dump__new(btf, NULL, &opts, btf_dump_printf);
	if (libbpf_get_error(d)) {
		fprintf(stderr, "Failed to create btf_dump instance: %ld\n", libbpf_get_error(d));
		return NULL;
		goto err_out;
	}

	for (i = 1; i < btf__type_cnt(btf); i++) {
		err = btf_dump__dump_type(d, i);
		if (err) {
			fprintf(stderr, "Failed to dump type [%d]: %d\n", i, err);
			return NULL;
			goto err_out;
		}
	}

	btf_dump__free(d);
	fflush(buf_file);
	fclose(buf_file);
	return buf;
err_out:
	btf_dump__free(d);
	fclose(buf_file);
	return NULL;
}
+4 −4
Original line number Diff line number Diff line
@@ -699,14 +699,13 @@ static void test_bpf_percpu_hash_map(void)
	char buf[64];
	void *val;

	val = malloc(8 * bpf_num_possible_cpus());

	skel = bpf_iter_bpf_percpu_hash_map__open();
	if (CHECK(!skel, "bpf_iter_bpf_percpu_hash_map__open",
		  "skeleton open failed\n"))
		return;

	skel->rodata->num_cpus = bpf_num_possible_cpus();
	val = malloc(8 * bpf_num_possible_cpus());

	err = bpf_iter_bpf_percpu_hash_map__load(skel);
	if (CHECK(!skel, "bpf_iter_bpf_percpu_hash_map__load",
@@ -770,6 +769,7 @@ static void test_bpf_percpu_hash_map(void)
	bpf_link__destroy(link);
out:
	bpf_iter_bpf_percpu_hash_map__destroy(skel);
	free(val);
}

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

	val = malloc(8 * bpf_num_possible_cpus());

	skel = bpf_iter_bpf_percpu_array_map__open();
	if (CHECK(!skel, "bpf_iter_bpf_percpu_array_map__open",
		  "skeleton open failed\n"))
		return;

	skel->rodata->num_cpus = bpf_num_possible_cpus();
	val = malloc(8 * bpf_num_possible_cpus());

	err = bpf_iter_bpf_percpu_array_map__load(skel);
	if (CHECK(!skel, "bpf_iter_bpf_percpu_array_map__load",
@@ -933,6 +932,7 @@ static void test_bpf_percpu_array_map(void)
	bpf_link__destroy(link);
out:
	bpf_iter_bpf_percpu_array_map__destroy(skel);
	free(val);
}

/* An iterator program deletes all local storage in a map. */
+2 −4
Original line number Diff line number Diff line
@@ -4046,11 +4046,9 @@ static void *btf_raw_create(const struct btf_header *hdr,
			next_str_idx < strs_cnt ? strs_idx[next_str_idx] : NULL;

done:
	free(strs_idx);
	if (err) {
		if (raw_btf)
		free(raw_btf);
		if (strs_idx)
			free(strs_idx);
		return NULL;
	}
	return raw_btf;
Loading