Skip to contentSkip to conversation

USB: serial: whiteheat: use stack instead of heap memory

PATCH In review Nam Cao 2 participants 3 messages Feb 4, 2023

Subsystems (2)
lore
Share & tools
lore

Nam Cao

author
#0 lore raw

PATCH 1/1 USB: serial: whiteheat: use stack instead of heap memory

Some buffers in whiteheat_attach() are small and only used locally. Move them to the stack to avoid complications with heap memory.

Compile-tested only.

---
 drivers/usb/serial/whiteheat.c | 25 ++++---------------------
 1 file changed, 4 insertions(+), 21 deletions(-)
drivers/usb/serial/whiteheat.c +4 -21
index 7f82d40753ee..4ad8915b536b 100644
@@ -220,22 +220,16 @@ static int whiteheat_attach(struct usb_serial *serial)
 	int pipe;
 	int ret;
 	int alen;
-	__u8 *command;
-	__u8 *result;
+	__u8 command[2];
+	__u8 result[sizeof(*hw_info) + 1];
 
 	command_port = serial->port[COMMAND_PORT];
 
 	pipe = usb_sndbulkpipe(serial->dev,
 			command_port->bulk_out_endpointAddress);
-	command = kmalloc(2, GFP_KERNEL);
-	if (!command)
-		goto no_command_buffer;
+
 	command[0] = WHITEHEAT_GET_HW_INFO;
 	command[1] = 0;
-
-	result = kmalloc(sizeof(*hw_info) + 1, GFP_KERNEL);
-	if (!result)
-		goto no_result_buffer;
 	/*
 	 * When the module is reloaded the firmware is still there and
 	 * the endpoints are still in the usb core unchanged. This is the
@@ -283,7 +277,7 @@ static int whiteheat_attach(struct usb_serial *serial)
 	command_info = kmalloc(sizeof(struct whiteheat_command_private),
 								GFP_KERNEL);
 	if (!command_info)
-		goto no_command_private;
+		return -ENOMEM;
 
 	mutex_init(&command_info->mutex);
 	command_info->port_running = 0;
@@ -291,8 +285,6 @@ static int whiteheat_attach(struct usb_serial *serial)
 	usb_set_serial_port_data(command_port, command_info);
 	command_port->write_urb->complete = command_port_write_callback;
 	command_port->read_urb->complete = command_port_read_callback;
-	kfree(result);
-	kfree(command);
 
 	return 0;
 
@@ -307,16 +299,7 @@ static int whiteheat_attach(struct usb_serial *serial)
 	dev_err(&serial->dev->dev,
 		"%s: please contact [email protected]\n",
 		serial->type->description);
-	kfree(result);
-	kfree(command);
 	return -ENODEV;
-
-no_command_private:
-	kfree(result);
-no_result_buffer:
-	kfree(command);
-no_command_buffer:
-	return -ENOMEM;
 }
 
 static void whiteheat_release(struct usb_serial *serial)
Signature · 1 line
2.34.1
#1 lore raw
Quoted 4 lines · Nam Cao

Some buffers in whiteheat_attach() are small and only used locally. Move them to the stack to avoid complications with heap memory.

Compile-tested only.

And that's the problem, you can't just compile test these things, the code will blow up if you make these changes :(

All USB transfers need to come from memory that can be safely DMAed. Stack memory is not that type of memory, you HAVE to allocate it dynamically from the heap in order to have this guarantee.

So no, this patch is not acceptable, sorry. You will see this pattern in all USB drivers, all data must be dynamically allocated, even for 2 byte commands.

So yes, there was a reason we added this "complexity" to the driver, it is required :)

sorry,

greg k-h

author
#2 lore raw
Quoted 14 lines · Greg Kroah-Hartman
Quoted 4 lines · Nam Cao

Some buffers in whiteheat_attach() are small and only used locally. Move them to the stack to avoid complications with heap memory.

Compile-tested only.

And that's the problem, you can't just compile test these things, the code will blow up if you make these changes :(

All USB transfers need to come from memory that can be safely DMAed. Stack memory is not that type of memory, you HAVE to allocate it dynamically from the heap in order to have this guarantee.

Quoted 6 lines

So no, this patch is not acceptable, sorry. You will see this pattern in all USB drivers, all data must be dynamically allocated, even for 2 byte commands.

So yes, there was a reason we added this "complexity" to the driver, it is required :)

Thanks for "the lecture", and sorry for the broken patch.

Best regards,
Nam