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 <[email protected]>
---
drivers/usb/serial/whiteheat.c | 25 ++++---------------------
1 file changed, 4 insertions(+), 21 deletions(-)
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 [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)
--
2.34.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
On Sat, Feb 4, 2023 at 2:55 PM Greg Kroah-Hartman
<[email protected]> 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