Commit 97c4e094 authored by Cosmin Ratiu's avatar Cosmin Ratiu Committed by Jakub Kicinski
Browse files

tests/ncdevmem: Fix double-free of queue array



netdev_bind_rx takes ownership of the queue array passed as parameter
and frees it, so a queue array buffer cannot be reused across multiple
netdev_bind_rx calls.

This commit fixes that by always passing in a newly created queue array
to all netdev_bind_rx calls in ncdevmem.

Fixes: 85585b4b ("selftests: add ncdevmem, netcat for devmem TCP")
Signed-off-by: default avatarCosmin Ratiu <cratiu@nvidia.com>
Acked-by: default avatarStanislav Fomichev <sdf@fomichev.me>
Reviewed-by: default avatarJoe Damato <jdamato@fastly.com>
Reviewed-by: default avatarMina Almasry <almasrymina@google.com>
Link: https://patch.msgid.link/20250508084434.1933069-1-cratiu@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent f11cf946
Loading
Loading
Loading
Loading
+22 −33
Original line number Diff line number Diff line
@@ -431,6 +431,22 @@ static int parse_address(const char *str, int port, struct sockaddr_in6 *sin6)
	return 0;
}

static struct netdev_queue_id *create_queues(void)
{
	struct netdev_queue_id *queues;
	size_t i = 0;

	queues = calloc(num_queues, sizeof(*queues));
	for (i = 0; i < num_queues; i++) {
		queues[i]._present.type = 1;
		queues[i]._present.id = 1;
		queues[i].type = NETDEV_QUEUE_TYPE_RX;
		queues[i].id = start_queue + i;
	}

	return queues;
}

int do_server(struct memory_buffer *mem)
{
	char ctrl_data[sizeof(int) * 20000];
@@ -448,7 +464,6 @@ int do_server(struct memory_buffer *mem)
	char buffer[256];
	int socket_fd;
	int client_fd;
	size_t i = 0;
	int ret;

	ret = parse_address(server_ip, atoi(port), &server_sin);
@@ -471,16 +486,7 @@ int do_server(struct memory_buffer *mem)

	sleep(1);

	queues = malloc(sizeof(*queues) * num_queues);

	for (i = 0; i < num_queues; i++) {
		queues[i]._present.type = 1;
		queues[i]._present.id = 1;
		queues[i].type = NETDEV_QUEUE_TYPE_RX;
		queues[i].id = start_queue + i;
	}

	if (bind_rx_queue(ifindex, mem->fd, queues, num_queues, &ys))
	if (bind_rx_queue(ifindex, mem->fd, create_queues(), num_queues, &ys))
		error(1, 0, "Failed to bind\n");

	tmp_mem = malloc(mem->size);
@@ -545,7 +551,6 @@ int do_server(struct memory_buffer *mem)
			goto cleanup;
		}

		i++;
		for (cm = CMSG_FIRSTHDR(&msg); cm; cm = CMSG_NXTHDR(&msg, cm)) {
			if (cm->cmsg_level != SOL_SOCKET ||
			    (cm->cmsg_type != SCM_DEVMEM_DMABUF &&
@@ -630,10 +635,8 @@ int do_server(struct memory_buffer *mem)

void run_devmem_tests(void)
{
	struct netdev_queue_id *queues;
	struct memory_buffer *mem;
	struct ynl_sock *ys;
	size_t i = 0;

	mem = provider->alloc(getpagesize() * NUM_PAGES);

@@ -641,38 +644,24 @@ void run_devmem_tests(void)
	if (configure_rss())
		error(1, 0, "rss error\n");

	queues = calloc(num_queues, sizeof(*queues));

	if (configure_headersplit(1))
		error(1, 0, "Failed to configure header split\n");

	if (!bind_rx_queue(ifindex, mem->fd, queues, num_queues, &ys))
	if (!bind_rx_queue(ifindex, mem->fd,
			   calloc(num_queues, sizeof(struct netdev_queue_id)),
			   num_queues, &ys))
		error(1, 0, "Binding empty queues array should have failed\n");

	for (i = 0; i < num_queues; i++) {
		queues[i]._present.type = 1;
		queues[i]._present.id = 1;
		queues[i].type = NETDEV_QUEUE_TYPE_RX;
		queues[i].id = start_queue + i;
	}

	if (configure_headersplit(0))
		error(1, 0, "Failed to configure header split\n");

	if (!bind_rx_queue(ifindex, mem->fd, queues, num_queues, &ys))
	if (!bind_rx_queue(ifindex, mem->fd, create_queues(), num_queues, &ys))
		error(1, 0, "Configure dmabuf with header split off should have failed\n");

	if (configure_headersplit(1))
		error(1, 0, "Failed to configure header split\n");

	for (i = 0; i < num_queues; i++) {
		queues[i]._present.type = 1;
		queues[i]._present.id = 1;
		queues[i].type = NETDEV_QUEUE_TYPE_RX;
		queues[i].id = start_queue + i;
	}

	if (bind_rx_queue(ifindex, mem->fd, queues, num_queues, &ys))
	if (bind_rx_queue(ifindex, mem->fd, create_queues(), num_queues, &ys))
		error(1, 0, "Failed to bind\n");

	/* Deactivating a bound queue should not be legal */