Skip to contentSkip to conversation

USB: serial: io_ti: fix information leak in completion handler

PATCH New Johan Hovold 1 participant 4 messages Mar 6, 2017 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

Johan Hovold

author maintainer
#1 lore raw

PATCH 1/5 USB: serial: io_ti: fix NULL-deref in interrupt callback

Fix a NULL-pointer dereference in the interrupt callback should a malicious device send data containing a bad port number by adding the missing sanity check.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc stable <[email protected]>
---
 drivers/usb/serial/io_ti.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/usb/serial/io_ti.c +6 -0
index ceaeebaa6f90..4561dd4cde8b 100644
@@ -1674,6 +1674,12 @@ static void edge_interrupt_callback(struct urb *urb)
 	function    = TIUMP_GET_FUNC_FROM_CODE(data[0]);
 	dev_dbg(dev, "%s - port_number %d, function %d, info 0x%x\n", __func__,
 		port_number, function, data[1]);
+
+	if (port_number >= edge_serial->serial->num_ports) {
+		dev_err(dev, "bad port number %d\n", port_number);
+		goto exit;
+	}
+
 	port = edge_serial->serial->port[port_number];
 	edge_port = usb_get_serial_port_data(port);
 	if (!edge_port) {
Signature · 1 line
2.12.0
author maintainer
#2 lore raw

PATCH 2/5 USB: serial: omninet: fix reference leaks at open

In reply to a message not in the archive

This driver needlessly took another reference to the tty on open, a reference which was then never released on close. This lead to not just a leak of the tty, but also a driver reference leak that prevented the driver from being unloaded after a port had once been opened.

Fixes 4a90f09b20f4 ("tty: usb-serial krefs")
Cc stable <[email protected]> # 2.6.28
---
 drivers/usb/serial/omninet.c | 6 ------
 1 file changed, 6 deletions(-)
drivers/usb/serial/omninet.c +0 -6
index a180b17d2432..76564b3bebb9 100644
@@ -142,12 +142,6 @@ static int omninet_port_remove(struct usb_serial_port *port)
 
 static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
-	struct usb_serial	*serial = port->serial;
-	struct usb_serial_port	*wport;
-
-	wport = serial->port[1];
-	tty_port_tty_set(&wport->port, tty);
-
 	return usb_serial_generic_open(tty, port);
 }
 
Signature · 1 line
2.12.0
author maintainer
#3 lore raw

PATCH 4/5 USB: serial: io_ti: fix information leak in completion handler

In reply to a message not in the archive

Add missing sanity check to the bulk-in completion handler to avoid an integer underflow that can be triggered by a malicious device.

This avoids leaking 128 kB of memory content from after the URB transfer buffer to user space.

Fixes 8c209e6782ca ("USB: make actual_length in struct urb field u32")
Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc stable <[email protected]> # 2.6.30
---
 drivers/usb/serial/io_ti.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/serial/io_ti.c +1 -1
index 4561dd4cde8b..a76b95d32157 100644
@@ -1761,7 +1761,7 @@ static void edge_bulk_in_callback(struct urb *urb)
 
 	port_number = edge_port->port->port_number;
 
-	if (edge_port->lsr_event) {
+	if (urb->actual_length > 0 && edge_port->lsr_event) {
 		edge_port->lsr_event = 0;
 		dev_dbg(dev, "%s ===== Port %u LSR Status = %02x, Data = %02x ======\n",
 			__func__, port_number, edge_port->lsr_mask, *data);
Signature · 1 line
2.12.0
author maintainer
#4 lore raw

PATCH 5/5 USB: serial: safe_serial: fix information leak in completion handler

In reply to a message not in the archive

Add missing sanity check to the bulk-in completion handler to avoid an integer underflow that could be triggered by a malicious device.

This avoids leaking up to 56 bytes from after the URB transfer buffer to user space.

Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc stable <[email protected]>
---
 drivers/usb/serial/safe_serial.c | 5 +++++
 1 file changed, 5 insertions(+)
drivers/usb/serial/safe_serial.c +5 -0
index 93c6c9b08daa..8a069aa154ed 100644
@@ -200,6 +200,11 @@ static void safe_process_read_urb(struct urb *urb)
 	if (!safe)
 		goto out;
 
+	if (length < 2) {
+		dev_err(&port->dev, "malformed packet\n");
+		return;
+	}
+
 	fcs = fcs_compute10(data, length, CRC10_INITFCS);
 	if (fcs) {
 		dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs);
Signature · 1 line
2.12.0