Commit 99fe8af0 authored by Yuan Chen's avatar Yuan Chen Committed by Alexei Starovoitov
Browse files

bpftool: Fix memory leak in dump_xx_nlmsg on realloc failure



In function dump_xx_nlmsg(), when realloc() fails to allocate memory,
the original pointer to the buffer is overwritten with NULL. This causes
a memory leak because the previously allocated buffer becomes unreachable
without being freed.

Fixes: 7900efc1 ("tools/bpf: bpftool: improve output format for bpftool net")
Signed-off-by: default avatarYuan Chen <chenyuan@kylinos.cn>
Reviewed-by: default avatarQuentin Monnet <qmo@kernel.org>
Link: https://lore.kernel.org/r/20250620012133.14819-1-chenyuan_fl@163.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent f8b19aec
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -366,17 +366,18 @@ static int dump_link_nlmsg(void *cookie, void *msg, struct nlattr **tb)
{
	struct bpf_netdev_t *netinfo = cookie;
	struct ifinfomsg *ifinfo = msg;
	struct ip_devname_ifindex *tmp;

	if (netinfo->filter_idx > 0 && netinfo->filter_idx != ifinfo->ifi_index)
		return 0;

	if (netinfo->used_len == netinfo->array_len) {
		netinfo->devices = realloc(netinfo->devices,
			(netinfo->array_len + 16) *
			sizeof(struct ip_devname_ifindex));
		if (!netinfo->devices)
		tmp = realloc(netinfo->devices,
			(netinfo->array_len + 16) * sizeof(struct ip_devname_ifindex));
		if (!tmp)
			return -ENOMEM;

		netinfo->devices = tmp;
		netinfo->array_len += 16;
	}
	netinfo->devices[netinfo->used_len].ifindex = ifinfo->ifi_index;
@@ -395,6 +396,7 @@ static int dump_class_qdisc_nlmsg(void *cookie, void *msg, struct nlattr **tb)
{
	struct bpf_tcinfo_t *tcinfo = cookie;
	struct tcmsg *info = msg;
	struct tc_kind_handle *tmp;

	if (tcinfo->is_qdisc) {
		/* skip clsact qdisc */
@@ -406,11 +408,12 @@ static int dump_class_qdisc_nlmsg(void *cookie, void *msg, struct nlattr **tb)
	}

	if (tcinfo->used_len == tcinfo->array_len) {
		tcinfo->handle_array = realloc(tcinfo->handle_array,
		tmp = realloc(tcinfo->handle_array,
			(tcinfo->array_len + 16) * sizeof(struct tc_kind_handle));
		if (!tcinfo->handle_array)
		if (!tmp)
			return -ENOMEM;

		tcinfo->handle_array = tmp;
		tcinfo->array_len += 16;
	}
	tcinfo->handle_array[tcinfo->used_len].handle = info->tcm_handle;