aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/io_ti.c
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2017-01-03 10:39:44 -0500
committerJohan Hovold <johan@kernel.org>2017-01-04 04:37:16 -0500
commit4f9785cc99feeb3673993b471f646b4dbaec2cc1 (patch)
tree94c1a64ad12028ac716e1e369bd937753a18180e /drivers/usb/serial/io_ti.c
parenta323fefc6f5079844dc62ffeb54f491d0242ca35 (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.c9
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
1514static int ti_do_config(struct edgeport_port *port, int feature, int on) 1514static 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;