Commit 2852f0fe authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman

[PATCH] USB: fix whiteheat doing DMA to stack

the whiteheat driver in two places does DMA to the stack by usb_bulk_msg().
parent b4f61c63
...@@ -353,8 +353,8 @@ static int whiteheat_attach (struct usb_serial *serial) ...@@ -353,8 +353,8 @@ static int whiteheat_attach (struct usb_serial *serial)
int pipe; int pipe;
int ret; int ret;
int alen; int alen;
__u8 command[2] = { WHITEHEAT_GET_HW_INFO, 0 }; __u8 *command;
__u8 result[sizeof(*hw_info) + 1]; __u8 *result;
int i; int i;
int j; int j;
struct urb *urb; struct urb *urb;
...@@ -365,13 +365,22 @@ static int whiteheat_attach (struct usb_serial *serial) ...@@ -365,13 +365,22 @@ static int whiteheat_attach (struct usb_serial *serial)
command_port = serial->port[COMMAND_PORT]; command_port = serial->port[COMMAND_PORT];
pipe = usb_sndbulkpipe (serial->dev, command_port->bulk_out_endpointAddress); pipe = usb_sndbulkpipe (serial->dev, command_port->bulk_out_endpointAddress);
command = kmalloc(2, GFP_KERNEL);
if (!command)
goto no_comand_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 * When the module is reloaded the firmware is still there and
* the endpoints are still in the usb core unchanged. This is the * the endpoints are still in the usb core unchanged. This is the
* unlinking bug in disguise. Same for the call below. * unlinking bug in disguise. Same for the call below.
*/ */
usb_clear_halt(serial->dev, pipe); usb_clear_halt(serial->dev, pipe);
ret = usb_bulk_msg (serial->dev, pipe, command, sizeof(command), &alen, COMMAND_TIMEOUT); ret = usb_bulk_msg (serial->dev, pipe, command, 2, &alen, COMMAND_TIMEOUT);
if (ret) { if (ret) {
err("%s: Couldn't send command [%d]", serial->type->name, ret); err("%s: Couldn't send command [%d]", serial->type->name, ret);
goto no_firmware; goto no_firmware;
...@@ -383,7 +392,7 @@ static int whiteheat_attach (struct usb_serial *serial) ...@@ -383,7 +392,7 @@ static int whiteheat_attach (struct usb_serial *serial)
pipe = usb_rcvbulkpipe (serial->dev, command_port->bulk_in_endpointAddress); pipe = usb_rcvbulkpipe (serial->dev, command_port->bulk_in_endpointAddress);
/* See the comment on the usb_clear_halt() above */ /* See the comment on the usb_clear_halt() above */
usb_clear_halt(serial->dev, pipe); usb_clear_halt(serial->dev, pipe);
ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, COMMAND_TIMEOUT); ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT);
if (ret) { if (ret) {
err("%s: Couldn't get results [%d]", serial->type->name, ret); err("%s: Couldn't get results [%d]", serial->type->name, ret);
goto no_firmware; goto no_firmware;
...@@ -485,6 +494,8 @@ static int whiteheat_attach (struct usb_serial *serial) ...@@ -485,6 +494,8 @@ static int whiteheat_attach (struct usb_serial *serial)
usb_set_serial_port_data(command_port, command_info); usb_set_serial_port_data(command_port, command_info);
command_port->write_urb->complete = command_port_write_callback; command_port->write_urb->complete = command_port_write_callback;
command_port->read_urb->complete = command_port_read_callback; command_port->read_urb->complete = command_port_read_callback;
kfree(result);
kfree(command);
return 0; return 0;
...@@ -526,6 +537,10 @@ static int whiteheat_attach (struct usb_serial *serial) ...@@ -526,6 +537,10 @@ static int whiteheat_attach (struct usb_serial *serial)
no_private: no_private:
; ;
} }
kfree(result);
no_result_buffer:
kfree(command):
no_command_buffer:
return -ENOMEM; return -ENOMEM;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment