mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	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: 85585b4bc8 ("selftests: add ncdevmem, netcat for devmem TCP")
Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Reviewed-by: Joe Damato <jdamato@fastly.com>
Reviewed-by: Mina Almasry <almasrymina@google.com>
Link: https://patch.msgid.link/20250508084434.1933069-1-cratiu@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									f11cf946c0
								
							
						
					
					
						commit
						97c4e094a4
					
				
					 1 changed files with 22 additions and 33 deletions
				
			
		|  | @ -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 */ | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Cosmin Ratiu
						Cosmin Ratiu