Commit 4842ed5b authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman Committed by Johan Hovold

USB: serial: visor: handle potential invalid device configuration

If we get an invalid device configuration from a palm 3 type device, we
might incorrectly parse things, and we have the potential to crash in
"interesting" ways.

Fix this up by verifying the size of the configuration passed to us by
the device, and only if it is correct, will we handle it.

Note that this also fixes an information leak of slab data.
Reported-by: default avatarAndrey Konovalov <andreyknvl@google.com>
Reviewed-by: default avatarAndrey Konovalov <andreyknvl@google.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
[ johan: add comment about the info leak ]
Cc: stable <stable@vger.kernel.org>
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
parent 4205cb01
...@@ -335,47 +335,48 @@ static int palm_os_3_probe(struct usb_serial *serial, ...@@ -335,47 +335,48 @@ static int palm_os_3_probe(struct usb_serial *serial,
goto exit; goto exit;
} }
if (retval == sizeof(*connection_info)) { if (retval != sizeof(*connection_info)) {
connection_info = (struct visor_connection_info *) dev_err(dev, "Invalid connection information received from device\n");
transfer_buffer; retval = -ENODEV;
goto exit;
num_ports = le16_to_cpu(connection_info->num_ports);
for (i = 0; i < num_ports; ++i) {
switch (
connection_info->connections[i].port_function_id) {
case VISOR_FUNCTION_GENERIC:
string = "Generic";
break;
case VISOR_FUNCTION_DEBUGGER:
string = "Debugger";
break;
case VISOR_FUNCTION_HOTSYNC:
string = "HotSync";
break;
case VISOR_FUNCTION_CONSOLE:
string = "Console";
break;
case VISOR_FUNCTION_REMOTE_FILE_SYS:
string = "Remote File System";
break;
default:
string = "unknown";
break;
}
dev_info(dev, "%s: port %d, is for %s use\n",
serial->type->description,
connection_info->connections[i].port, string);
}
} }
/*
* Handle devices that report invalid stuff here. connection_info = (struct visor_connection_info *)transfer_buffer;
*/
num_ports = le16_to_cpu(connection_info->num_ports);
/* Handle devices that report invalid stuff here. */
if (num_ports == 0 || num_ports > 2) { if (num_ports == 0 || num_ports > 2) {
dev_warn(dev, "%s: No valid connect info available\n", dev_warn(dev, "%s: No valid connect info available\n",
serial->type->description); serial->type->description);
num_ports = 2; num_ports = 2;
} }
for (i = 0; i < num_ports; ++i) {
switch (connection_info->connections[i].port_function_id) {
case VISOR_FUNCTION_GENERIC:
string = "Generic";
break;
case VISOR_FUNCTION_DEBUGGER:
string = "Debugger";
break;
case VISOR_FUNCTION_HOTSYNC:
string = "HotSync";
break;
case VISOR_FUNCTION_CONSOLE:
string = "Console";
break;
case VISOR_FUNCTION_REMOTE_FILE_SYS:
string = "Remote File System";
break;
default:
string = "unknown";
break;
}
dev_info(dev, "%s: port %d, is for %s use\n",
serial->type->description,
connection_info->connections[i].port, string);
}
dev_info(dev, "%s: Number of ports: %d\n", serial->type->description, dev_info(dev, "%s: Number of ports: %d\n", serial->type->description,
num_ports); num_ports);
......
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