diff options
author | Johan Hovold <johan@kernel.org> | 2017-01-03 10:39:44 -0500 |
---|---|---|
committer | Johan Hovold <johan@kernel.org> | 2017-01-04 04:37:16 -0500 |
commit | 4f9785cc99feeb3673993b471f646b4dbaec2cc1 (patch) | |
tree | 94c1a64ad12028ac716e1e369bd937753a18180e /drivers/usb/serial/io_ti.c | |
parent | a323fefc6f5079844dc62ffeb54f491d0242ca35 (diff) |
USB: serial: io_ti: fix another NULL-deref at open
In case a device is left in "boot-mode" we must not register any port
devices in order to avoid a NULL-pointer dereference on open due to
missing endpoints. This could be used by a malicious device to trigger
an OOPS:
Unable to handle kernel NULL pointer dereference at virtual address 00000030
...
[<bf0caa84>] (edge_open [io_ti]) from [<bf0b0118>] (serial_port_activate+0x68/0x98 [usbserial])
[<bf0b0118>] (serial_port_activate [usbserial]) from [<c0470ca4>] (tty_port_open+0x9c/0xe8)
[<c0470ca4>] (tty_port_open) from [<bf0b0da0>] (serial_open+0x48/0x6c [usbserial])
[<bf0b0da0>] (serial_open [usbserial]) from [<c0469178>] (tty_open+0xcc/0x5cc)
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Diffstat (limited to 'drivers/usb/serial/io_ti.c')
-rw-r--r-- | drivers/usb/serial/io_ti.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index bf8a4f432f4b..3b1cfba0ec84 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -1508,7 +1508,7 @@ stayinbootmode: | |||
1508 | dev_dbg(dev, "%s - STAYING IN BOOT MODE\n", __func__); | 1508 | dev_dbg(dev, "%s - STAYING IN BOOT MODE\n", __func__); |
1509 | serial->product_info.TiMode = TI_MODE_BOOT; | 1509 | serial->product_info.TiMode = TI_MODE_BOOT; |
1510 | 1510 | ||
1511 | return 0; | 1511 | return 1; |
1512 | } | 1512 | } |
1513 | 1513 | ||
1514 | static int ti_do_config(struct edgeport_port *port, int feature, int on) | 1514 | static int ti_do_config(struct edgeport_port *port, int feature, int on) |
@@ -2560,14 +2560,18 @@ static int edge_startup(struct usb_serial *serial) | |||
2560 | 2560 | ||
2561 | mutex_init(&edge_serial->es_lock); | 2561 | mutex_init(&edge_serial->es_lock); |
2562 | edge_serial->serial = serial; | 2562 | edge_serial->serial = serial; |
2563 | INIT_DELAYED_WORK(&edge_serial->heartbeat_work, edge_heartbeat_work); | ||
2563 | usb_set_serial_data(serial, edge_serial); | 2564 | usb_set_serial_data(serial, edge_serial); |
2564 | 2565 | ||
2565 | status = download_fw(edge_serial); | 2566 | status = download_fw(edge_serial); |
2566 | if (status) { | 2567 | if (status < 0) { |
2567 | kfree(edge_serial); | 2568 | kfree(edge_serial); |
2568 | return status; | 2569 | return status; |
2569 | } | 2570 | } |
2570 | 2571 | ||
2572 | if (status > 0) | ||
2573 | return 1; /* bind but do not register any ports */ | ||
2574 | |||
2571 | product_id = le16_to_cpu( | 2575 | product_id = le16_to_cpu( |
2572 | edge_serial->serial->dev->descriptor.idProduct); | 2576 | edge_serial->serial->dev->descriptor.idProduct); |
2573 | 2577 | ||
@@ -2579,7 +2583,6 @@ static int edge_startup(struct usb_serial *serial) | |||
2579 | } | 2583 | } |
2580 | } | 2584 | } |
2581 | 2585 | ||
2582 | INIT_DELAYED_WORK(&edge_serial->heartbeat_work, edge_heartbeat_work); | ||
2583 | edge_heartbeat_schedule(edge_serial); | 2586 | edge_heartbeat_schedule(edge_serial); |
2584 | 2587 | ||
2585 | return 0; | 2588 | return 0; |