diff mbox series

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

Message ID 20230204134651.22569-1-namcaov@gmail.com (mailing list archive)
State New, archived
Headers show
Series USB: serial: whiteheat: use stack instead of heap memory | expand

Commit Message

Nam Cao Feb. 4, 2023, 1:46 p.m. UTC
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.

Signed-off-by: Nam Cao <namcaov@gmail.com>
---
 drivers/usb/serial/whiteheat.c | 25 ++++---------------------
 1 file changed, 4 insertions(+), 21 deletions(-)

Comments

Greg Kroah-Hartman Feb. 4, 2023, 1:55 p.m. UTC | #1
On Sat, Feb 04, 2023 at 02:46:51PM +0100, Nam Cao wrote:
> 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
Nam Cao Feb. 4, 2023, 2:01 p.m. UTC | #2
On Sat, Feb 4, 2023 at 2:55 PM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> On Sat, Feb 04, 2023 at 02:46:51PM +0100, Nam Cao wrote:
> > 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 :)

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

Best regards,
Nam
diff mbox series

Patch

diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 7f82d40753ee..4ad8915b536b 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -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 support@connecttech.com\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)