From ce0bd28f8b229bacce7b49ac1a936fcc0d864175 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 1 Apr 2013 15:38:43 -0700 Subject: [PATCH] 3.8-stable patches added patches: usb-ark3116-fix-use-after-free-in-tiocmiwait.patch usb-ch341-fix-use-after-free-in-tiocmiwait.patch usb-cypress_m8-fix-use-after-free-in-tiocmiwait.patch usb-f81232-fix-use-after-free-in-tiocmiwait.patch usb-ftdi_sio-fix-use-after-free-in-tiocmiwait.patch usb-io_edgeport-fix-use-after-free-in-tiocmiwait.patch usb-io_ti-fix-use-after-free-in-tiocmiwait.patch usb-mct_u232-fix-use-after-free-in-tiocmiwait.patch usb-mos7840-fix-broken-tiocmiwait.patch usb-mos7840-fix-use-after-free-in-tiocmiwait.patch usb-oti6858-fix-use-after-free-in-tiocmiwait.patch usb-pl2303-fix-use-after-free-in-tiocmiwait.patch usb-quatech2-fix-use-after-free-in-tiocmiwait.patch usb-spcp8x5-fix-use-after-free-in-tiocmiwait.patch usb-ssu100-fix-use-after-free-in-tiocmiwait.patch usb-ti_usb_3410_5052-fix-use-after-free-in-tiocmiwait.patch --- queue-3.8/series | 16 +++ ...116-fix-use-after-free-in-tiocmiwait.patch | 65 ++++++++++++ ...341-fix-use-after-free-in-tiocmiwait.patch | 74 ++++++++++++++ ..._m8-fix-use-after-free-in-tiocmiwait.patch | 72 ++++++++++++++ ...232-fix-use-after-free-in-tiocmiwait.patch | 65 ++++++++++++ ...sio-fix-use-after-free-in-tiocmiwait.patch | 98 +++++++++++++++++++ ...ort-fix-use-after-free-in-tiocmiwait.patch | 69 +++++++++++++ ..._ti-fix-use-after-free-in-tiocmiwait.patch | 67 +++++++++++++ ...232-fix-use-after-free-in-tiocmiwait.patch | 70 +++++++++++++ .../usb-mos7840-fix-broken-tiocmiwait.patch | 42 ++++++++ ...840-fix-use-after-free-in-tiocmiwait.patch | 70 +++++++++++++ ...858-fix-use-after-free-in-tiocmiwait.patch | 66 +++++++++++++ ...303-fix-use-after-free-in-tiocmiwait.patch | 74 ++++++++++++++ ...ch2-fix-use-after-free-in-tiocmiwait.patch | 71 ++++++++++++++ ...8x5-fix-use-after-free-in-tiocmiwait.patch | 66 +++++++++++++ ...100-fix-use-after-free-in-tiocmiwait.patch | 71 ++++++++++++++ ...052-fix-use-after-free-in-tiocmiwait.patch | 64 ++++++++++++ 17 files changed, 1120 insertions(+) create mode 100644 queue-3.8/usb-ark3116-fix-use-after-free-in-tiocmiwait.patch create mode 100644 queue-3.8/usb-ch341-fix-use-after-free-in-tiocmiwait.patch create mode 100644 queue-3.8/usb-cypress_m8-fix-use-after-free-in-tiocmiwait.patch create mode 100644 queue-3.8/usb-f81232-fix-use-after-free-in-tiocmiwait.patch create mode 100644 queue-3.8/usb-ftdi_sio-fix-use-after-free-in-tiocmiwait.patch create mode 100644 queue-3.8/usb-io_edgeport-fix-use-after-free-in-tiocmiwait.patch create mode 100644 queue-3.8/usb-io_ti-fix-use-after-free-in-tiocmiwait.patch create mode 100644 queue-3.8/usb-mct_u232-fix-use-after-free-in-tiocmiwait.patch create mode 100644 queue-3.8/usb-mos7840-fix-broken-tiocmiwait.patch create mode 100644 queue-3.8/usb-mos7840-fix-use-after-free-in-tiocmiwait.patch create mode 100644 queue-3.8/usb-oti6858-fix-use-after-free-in-tiocmiwait.patch create mode 100644 queue-3.8/usb-pl2303-fix-use-after-free-in-tiocmiwait.patch create mode 100644 queue-3.8/usb-quatech2-fix-use-after-free-in-tiocmiwait.patch create mode 100644 queue-3.8/usb-spcp8x5-fix-use-after-free-in-tiocmiwait.patch create mode 100644 queue-3.8/usb-ssu100-fix-use-after-free-in-tiocmiwait.patch create mode 100644 queue-3.8/usb-ti_usb_3410_5052-fix-use-after-free-in-tiocmiwait.patch diff --git a/queue-3.8/series b/queue-3.8/series index 1e670a9a0bf..51fe26aa909 100644 --- a/queue-3.8/series +++ b/queue-3.8/series @@ -58,3 +58,19 @@ btrfs-limit-the-global-reserve-to-512mb.patch btrfs-don-t-drop-path-when-printing-out-tree-errors-in-scrub.patch usb-serial-add-modem-status-change-wait-queue.patch usb-serial-fix-hang-when-opening-port.patch +usb-quatech2-fix-use-after-free-in-tiocmiwait.patch +usb-mos7840-fix-broken-tiocmiwait.patch +usb-io_ti-fix-use-after-free-in-tiocmiwait.patch +usb-oti6858-fix-use-after-free-in-tiocmiwait.patch +usb-ftdi_sio-fix-use-after-free-in-tiocmiwait.patch +usb-pl2303-fix-use-after-free-in-tiocmiwait.patch +usb-mos7840-fix-use-after-free-in-tiocmiwait.patch +usb-spcp8x5-fix-use-after-free-in-tiocmiwait.patch +usb-ssu100-fix-use-after-free-in-tiocmiwait.patch +usb-ch341-fix-use-after-free-in-tiocmiwait.patch +usb-io_edgeport-fix-use-after-free-in-tiocmiwait.patch +usb-f81232-fix-use-after-free-in-tiocmiwait.patch +usb-ark3116-fix-use-after-free-in-tiocmiwait.patch +usb-mct_u232-fix-use-after-free-in-tiocmiwait.patch +usb-cypress_m8-fix-use-after-free-in-tiocmiwait.patch +usb-ti_usb_3410_5052-fix-use-after-free-in-tiocmiwait.patch diff --git a/queue-3.8/usb-ark3116-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-ark3116-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..156f56d3233 --- /dev/null +++ b/queue-3.8/usb-ark3116-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,65 @@ +From 5018860321dc7a9e50a75d5f319bc981298fb5b7 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:11 +0100 +Subject: USB: ark3116: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit 5018860321dc7a9e50a75d5f319bc981298fb5b7 upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ark3116.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/usb/serial/ark3116.c ++++ b/drivers/usb/serial/ark3116.c +@@ -62,7 +62,6 @@ static int is_irda(struct usb_serial *se + } + + struct ark3116_private { +- wait_queue_head_t delta_msr_wait; + struct async_icount icount; + int irda; /* 1 for irda device */ + +@@ -146,7 +145,6 @@ static int ark3116_port_probe(struct usb + if (!priv) + return -ENOMEM; + +- init_waitqueue_head(&priv->delta_msr_wait); + mutex_init(&priv->hw_lock); + spin_lock_init(&priv->status_lock); + +@@ -456,10 +454,14 @@ static int ark3116_ioctl(struct tty_stru + case TIOCMIWAIT: + for (;;) { + struct async_icount prev = priv->icount; +- interruptible_sleep_on(&priv->delta_msr_wait); ++ interruptible_sleep_on(&port->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; ++ ++ if (port->serial->disconnected) ++ return -EIO; ++ + if ((prev.rng == priv->icount.rng) && + (prev.dsr == priv->icount.dsr) && + (prev.dcd == priv->icount.dcd) && +@@ -580,7 +582,7 @@ static void ark3116_update_msr(struct us + priv->icount.dcd++; + if (msr & UART_MSR_TERI) + priv->icount.rng++; +- wake_up_interruptible(&priv->delta_msr_wait); ++ wake_up_interruptible(&port->delta_msr_wait); + } + } + diff --git a/queue-3.8/usb-ch341-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-ch341-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..e4d81019038 --- /dev/null +++ b/queue-3.8/usb-ch341-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,74 @@ +From fa1e11d5231c001c80a479160b5832933c5d35fb Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:12 +0100 +Subject: USB: ch341: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit fa1e11d5231c001c80a479160b5832933c5d35fb upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ch341.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -80,7 +80,6 @@ MODULE_DEVICE_TABLE(usb, id_table); + + struct ch341_private { + spinlock_t lock; /* access lock */ +- wait_queue_head_t delta_msr_wait; /* wait queue for modem status */ + unsigned baud_rate; /* set baud rate */ + u8 line_control; /* set line control value RTS/DTR */ + u8 line_status; /* active status of modem control inputs */ +@@ -252,7 +251,6 @@ static int ch341_port_probe(struct usb_s + return -ENOMEM; + + spin_lock_init(&priv->lock); +- init_waitqueue_head(&priv->delta_msr_wait); + priv->baud_rate = DEFAULT_BAUD_RATE; + priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; + +@@ -298,7 +296,7 @@ static void ch341_dtr_rts(struct usb_ser + priv->line_control &= ~(CH341_BIT_RTS | CH341_BIT_DTR); + spin_unlock_irqrestore(&priv->lock, flags); + ch341_set_handshake(port->serial->dev, priv->line_control); +- wake_up_interruptible(&priv->delta_msr_wait); ++ wake_up_interruptible(&port->delta_msr_wait); + } + + static void ch341_close(struct usb_serial_port *port) +@@ -491,7 +489,7 @@ static void ch341_read_int_callback(stru + tty_kref_put(tty); + } + +- wake_up_interruptible(&priv->delta_msr_wait); ++ wake_up_interruptible(&port->delta_msr_wait); + } + + exit: +@@ -517,11 +515,14 @@ static int wait_modem_info(struct usb_se + spin_unlock_irqrestore(&priv->lock, flags); + + while (!multi_change) { +- interruptible_sleep_on(&priv->delta_msr_wait); ++ interruptible_sleep_on(&port->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; + ++ if (port->serial->disconnected) ++ return -EIO; ++ + spin_lock_irqsave(&priv->lock, flags); + status = priv->line_status; + multi_change = priv->multi_status_change; diff --git a/queue-3.8/usb-cypress_m8-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-cypress_m8-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..cad00a38301 --- /dev/null +++ b/queue-3.8/usb-cypress_m8-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,72 @@ +From 356050d8b1e526db093e9d2c78daf49d6bf418e3 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:13 +0100 +Subject: USB: cypress_m8: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit 356050d8b1e526db093e9d2c78daf49d6bf418e3 upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +Also remove bogus test for private data pointer being NULL as it is +never assigned in the loop. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/cypress_m8.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +--- a/drivers/usb/serial/cypress_m8.c ++++ b/drivers/usb/serial/cypress_m8.c +@@ -111,7 +111,6 @@ struct cypress_private { + int baud_rate; /* stores current baud rate in + integer form */ + int isthrottled; /* if throttled, discard reads */ +- wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ + char prev_status, diff_status; /* used for TIOCMIWAIT */ + /* we pass a pointer to this as the argument sent to + cypress_set_termios old_termios */ +@@ -449,7 +448,6 @@ static int cypress_generic_port_probe(st + kfree(priv); + return -ENOMEM; + } +- init_waitqueue_head(&priv->delta_msr_wait); + + usb_reset_configuration(serial->dev); + +@@ -868,12 +866,16 @@ static int cypress_ioctl(struct tty_stru + switch (cmd) { + /* This code comes from drivers/char/serial.c and ftdi_sio.c */ + case TIOCMIWAIT: +- while (priv != NULL) { +- interruptible_sleep_on(&priv->delta_msr_wait); ++ for (;;) { ++ interruptible_sleep_on(&port->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; +- else { ++ ++ if (port->serial->disconnected) ++ return -EIO; ++ ++ { + char diff = priv->diff_status; + if (diff == 0) + return -EIO; /* no change => error */ +@@ -1187,7 +1189,7 @@ static void cypress_read_int_callback(st + if (priv->current_status != priv->prev_status) { + priv->diff_status |= priv->current_status ^ + priv->prev_status; +- wake_up_interruptible(&priv->delta_msr_wait); ++ wake_up_interruptible(&port->delta_msr_wait); + priv->prev_status = priv->current_status; + } + spin_unlock_irqrestore(&priv->lock, flags); diff --git a/queue-3.8/usb-f81232-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-f81232-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..d6213d149c0 --- /dev/null +++ b/queue-3.8/usb-f81232-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,65 @@ +From 508f940f1407656076a2e7d8f7fa059b567ecac2 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:14 +0100 +Subject: USB: f81232: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit 508f940f1407656076a2e7d8f7fa059b567ecac2 upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/f81232.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/usb/serial/f81232.c ++++ b/drivers/usb/serial/f81232.c +@@ -47,7 +47,6 @@ MODULE_DEVICE_TABLE(usb, id_table); + + struct f81232_private { + spinlock_t lock; +- wait_queue_head_t delta_msr_wait; + u8 line_control; + u8 line_status; + }; +@@ -112,7 +111,7 @@ static void f81232_process_read_urb(stru + line_status = priv->line_status; + priv->line_status &= ~UART_STATE_TRANSIENT_MASK; + spin_unlock_irqrestore(&priv->lock, flags); +- wake_up_interruptible(&priv->delta_msr_wait); ++ wake_up_interruptible(&port->delta_msr_wait); + + if (!urb->actual_length) + return; +@@ -261,11 +260,14 @@ static int wait_modem_info(struct usb_se + spin_unlock_irqrestore(&priv->lock, flags); + + while (1) { +- interruptible_sleep_on(&priv->delta_msr_wait); ++ interruptible_sleep_on(&port->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; + ++ if (port->serial->disconnected) ++ return -EIO; ++ + spin_lock_irqsave(&priv->lock, flags); + status = priv->line_status; + spin_unlock_irqrestore(&priv->lock, flags); +@@ -327,7 +329,6 @@ static int f81232_port_probe(struct usb_ + return -ENOMEM; + + spin_lock_init(&priv->lock); +- init_waitqueue_head(&priv->delta_msr_wait); + + usb_set_serial_port_data(port, priv); + diff --git a/queue-3.8/usb-ftdi_sio-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-ftdi_sio-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..3d916e03305 --- /dev/null +++ b/queue-3.8/usb-ftdi_sio-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,98 @@ +From 71ccb9b01981fabae27d3c98260ea4613207618e Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:15 +0100 +Subject: USB: ftdi_sio: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit 71ccb9b01981fabae27d3c98260ea4613207618e upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +When switching to tty ports, some lifetime assumptions were changed. +Specifically, close can now be called before the final tty reference is +dropped as part of hangup at device disconnect. Even with the ftdi +private-data refcounting this means that the port private data can be +freed while a process is sleeping on modem-status changes and thus +cannot be relied on to detect disconnects when woken up. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ftdi_sio.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -69,9 +69,7 @@ struct ftdi_private { + int flags; /* some ASYNC_xxxx flags are supported */ + unsigned long last_dtr_rts; /* saved modem control outputs */ + struct async_icount icount; +- wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ + char prev_status; /* Used for TIOCMIWAIT */ +- bool dev_gone; /* Used to abort TIOCMIWAIT */ + char transmit_empty; /* If transmitter is empty or not */ + __u16 interface; /* FT2232C, FT2232H or FT4232H port interface + (0 for FT232/245) */ +@@ -1692,10 +1690,8 @@ static int ftdi_sio_port_probe(struct us + + kref_init(&priv->kref); + mutex_init(&priv->cfg_lock); +- init_waitqueue_head(&priv->delta_msr_wait); + + priv->flags = ASYNC_LOW_LATENCY; +- priv->dev_gone = false; + + if (quirk && quirk->port_probe) + quirk->port_probe(priv); +@@ -1841,8 +1837,7 @@ static int ftdi_sio_port_remove(struct u + { + struct ftdi_private *priv = usb_get_serial_port_data(port); + +- priv->dev_gone = true; +- wake_up_interruptible_all(&priv->delta_msr_wait); ++ wake_up_interruptible(&port->delta_msr_wait); + + remove_sysfs_attrs(port); + +@@ -1991,7 +1986,7 @@ static int ftdi_process_packet(struct tt + if (diff_status & FTDI_RS0_RLSD) + priv->icount.dcd++; + +- wake_up_interruptible_all(&priv->delta_msr_wait); ++ wake_up_interruptible(&port->delta_msr_wait); + priv->prev_status = status; + } + +@@ -2448,11 +2443,15 @@ static int ftdi_ioctl(struct tty_struct + */ + case TIOCMIWAIT: + cprev = priv->icount; +- while (!priv->dev_gone) { +- interruptible_sleep_on(&priv->delta_msr_wait); ++ for (;;) { ++ interruptible_sleep_on(&port->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; ++ ++ if (port->serial->disconnected) ++ return -EIO; ++ + cnow = priv->icount; + if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || + ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || +@@ -2462,8 +2461,6 @@ static int ftdi_ioctl(struct tty_struct + } + cprev = cnow; + } +- return -EIO; +- break; + case TIOCSERGETLSR: + return get_lsr_info(port, (struct serial_struct __user *)arg); + break; diff --git a/queue-3.8/usb-io_edgeport-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-io_edgeport-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..9398d53b3bf --- /dev/null +++ b/queue-3.8/usb-io_edgeport-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,69 @@ +From 333576255d4cfc53efd056aad438568184b36af6 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:16 +0100 +Subject: USB: io_edgeport: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit 333576255d4cfc53efd056aad438568184b36af6 upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/io_edgeport.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/usb/serial/io_edgeport.c ++++ b/drivers/usb/serial/io_edgeport.c +@@ -110,7 +110,6 @@ struct edgeport_port { + wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ + wait_queue_head_t wait_open; /* for handling sleeping while waiting for open to finish */ + wait_queue_head_t wait_command; /* for handling sleeping while waiting for command to finish */ +- wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ + + struct async_icount icount; + struct usb_serial_port *port; /* loop back to the owner of this object */ +@@ -884,7 +883,6 @@ static int edge_open(struct tty_struct * + /* initialize our wait queues */ + init_waitqueue_head(&edge_port->wait_open); + init_waitqueue_head(&edge_port->wait_chase); +- init_waitqueue_head(&edge_port->delta_msr_wait); + init_waitqueue_head(&edge_port->wait_command); + + /* initialize our icount structure */ +@@ -1669,13 +1667,17 @@ static int edge_ioctl(struct tty_struct + dev_dbg(&port->dev, "%s (%d) TIOCMIWAIT\n", __func__, port->number); + cprev = edge_port->icount; + while (1) { +- prepare_to_wait(&edge_port->delta_msr_wait, ++ prepare_to_wait(&port->delta_msr_wait, + &wait, TASK_INTERRUPTIBLE); + schedule(); +- finish_wait(&edge_port->delta_msr_wait, &wait); ++ finish_wait(&port->delta_msr_wait, &wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; ++ ++ if (port->serial->disconnected) ++ return -EIO; ++ + cnow = edge_port->icount; + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) +@@ -2055,7 +2057,7 @@ static void handle_new_msr(struct edgepo + icount->dcd++; + if (newMsr & EDGEPORT_MSR_DELTA_RI) + icount->rng++; +- wake_up_interruptible(&edge_port->delta_msr_wait); ++ wake_up_interruptible(&edge_port->port->delta_msr_wait); + } + + /* Save the new modem status */ diff --git a/queue-3.8/usb-io_ti-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-io_ti-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..2f494393199 --- /dev/null +++ b/queue-3.8/usb-io_ti-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,67 @@ +From 7b2459690584f239650a365f3411ba2ec1c6d1e0 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:17 +0100 +Subject: USB: io_ti: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit 7b2459690584f239650a365f3411ba2ec1c6d1e0 upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/io_ti.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/usb/serial/io_ti.c ++++ b/drivers/usb/serial/io_ti.c +@@ -87,9 +87,6 @@ struct edgeport_port { + int close_pending; + int lsr_event; + struct async_icount icount; +- wait_queue_head_t delta_msr_wait; /* for handling sleeping while +- waiting for msr change to +- happen */ + struct edgeport_serial *edge_serial; + struct usb_serial_port *port; + __u8 bUartMode; /* Port type, 0: RS232, etc. */ +@@ -1518,7 +1515,7 @@ static void handle_new_msr(struct edgepo + icount->dcd++; + if (msr & EDGEPORT_MSR_DELTA_RI) + icount->rng++; +- wake_up_interruptible(&edge_port->delta_msr_wait); ++ wake_up_interruptible(&edge_port->port->delta_msr_wait); + } + + /* Save the new modem status */ +@@ -1821,7 +1818,6 @@ static int edge_open(struct tty_struct * + dev = port->serial->dev; + + memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount)); +- init_waitqueue_head(&edge_port->delta_msr_wait); + + /* turn off loopback */ + status = ti_do_config(edge_port, UMPC_SET_CLR_LOOPBACK, 0); +@@ -2488,10 +2484,14 @@ static int edge_ioctl(struct tty_struct + dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__); + cprev = edge_port->icount; + while (1) { +- interruptible_sleep_on(&edge_port->delta_msr_wait); ++ interruptible_sleep_on(&port->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; ++ ++ if (port->serial->disconnected) ++ return -EIO; ++ + cnow = edge_port->icount; + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) diff --git a/queue-3.8/usb-mct_u232-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-mct_u232-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..e6dc555028e --- /dev/null +++ b/queue-3.8/usb-mct_u232-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,70 @@ +From cf1d24443677a0758cfa88ca40f24858b89261c0 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:18 +0100 +Subject: USB: mct_u232: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit cf1d24443677a0758cfa88ca40f24858b89261c0 upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/mct_u232.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- a/drivers/usb/serial/mct_u232.c ++++ b/drivers/usb/serial/mct_u232.c +@@ -114,8 +114,6 @@ struct mct_u232_private { + unsigned char last_msr; /* Modem Status Register */ + unsigned int rx_flags; /* Throttling flags */ + struct async_icount icount; +- wait_queue_head_t msr_wait; /* for handling sleeping while waiting +- for msr change to happen */ + }; + + #define THROTTLED 0x01 +@@ -409,7 +407,6 @@ static int mct_u232_port_probe(struct us + return -ENOMEM; + + spin_lock_init(&priv->lock); +- init_waitqueue_head(&priv->msr_wait); + + usb_set_serial_port_data(port, priv); + +@@ -606,7 +603,7 @@ static void mct_u232_read_int_callback(s + tty_kref_put(tty); + } + #endif +- wake_up_interruptible(&priv->msr_wait); ++ wake_up_interruptible(&port->delta_msr_wait); + spin_unlock_irqrestore(&priv->lock, flags); + exit: + retval = usb_submit_urb(urb, GFP_ATOMIC); +@@ -815,13 +812,17 @@ static int mct_u232_ioctl(struct tty_st + cprev = mct_u232_port->icount; + spin_unlock_irqrestore(&mct_u232_port->lock, flags); + for ( ; ; ) { +- prepare_to_wait(&mct_u232_port->msr_wait, ++ prepare_to_wait(&port->delta_msr_wait, + &wait, TASK_INTERRUPTIBLE); + schedule(); +- finish_wait(&mct_u232_port->msr_wait, &wait); ++ finish_wait(&port->delta_msr_wait, &wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; ++ ++ if (port->serial->disconnected) ++ return -EIO; ++ + spin_lock_irqsave(&mct_u232_port->lock, flags); + cnow = mct_u232_port->icount; + spin_unlock_irqrestore(&mct_u232_port->lock, flags); diff --git a/queue-3.8/usb-mos7840-fix-broken-tiocmiwait.patch b/queue-3.8/usb-mos7840-fix-broken-tiocmiwait.patch new file mode 100644 index 00000000000..de933e16939 --- /dev/null +++ b/queue-3.8/usb-mos7840-fix-broken-tiocmiwait.patch @@ -0,0 +1,42 @@ +From e670c6af12517d08a403487b1122eecf506021cf Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:19 +0100 +Subject: USB: mos7840: fix broken TIOCMIWAIT + +From: Johan Hovold + +commit e670c6af12517d08a403487b1122eecf506021cf upstream. + +Make sure waiting processes are woken on modem-status changes. + +Currently processes are only woken on termios changes regardless of +whether the modem status has changed. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/mos7840.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/usb/serial/mos7840.c ++++ b/drivers/usb/serial/mos7840.c +@@ -423,6 +423,9 @@ static void mos7840_handle_new_msr(struc + icount->rng++; + smp_wmb(); + } ++ ++ mos7840_port->delta_msr_cond = 1; ++ wake_up_interruptible(&mos7840_port->delta_msr_wait); + } + } + +@@ -2021,8 +2024,6 @@ static void mos7840_change_port_settings + mos7840_port->read_urb_busy = false; + } + } +- wake_up(&mos7840_port->delta_msr_wait); +- mos7840_port->delta_msr_cond = 1; + dev_dbg(&port->dev, "%s - mos7840_port->shadowLCR is End %x\n", __func__, + mos7840_port->shadowLCR); + } diff --git a/queue-3.8/usb-mos7840-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-mos7840-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..363d17d2eed --- /dev/null +++ b/queue-3.8/usb-mos7840-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,70 @@ +From a14430db686b8e459e1cf070a6ecf391515c9ab9 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:20 +0100 +Subject: USB: mos7840: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit a14430db686b8e459e1cf070a6ecf391515c9ab9 upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/mos7840.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- a/drivers/usb/serial/mos7840.c ++++ b/drivers/usb/serial/mos7840.c +@@ -219,7 +219,6 @@ struct moschip_port { + char open; + char open_ports; + wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ +- wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ + int delta_msr_cond; + struct async_icount icount; + struct usb_serial_port *port; /* loop back to the owner of this object */ +@@ -425,7 +424,7 @@ static void mos7840_handle_new_msr(struc + } + + mos7840_port->delta_msr_cond = 1; +- wake_up_interruptible(&mos7840_port->delta_msr_wait); ++ wake_up_interruptible(&port->port->delta_msr_wait); + } + } + +@@ -1134,7 +1133,6 @@ static int mos7840_open(struct tty_struc + + /* initialize our wait queues */ + init_waitqueue_head(&mos7840_port->wait_chase); +- init_waitqueue_head(&mos7840_port->delta_msr_wait); + + /* initialize our icount structure */ + memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount)); +@@ -2224,13 +2222,18 @@ static int mos7840_ioctl(struct tty_stru + while (1) { + /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */ + mos7840_port->delta_msr_cond = 0; +- wait_event_interruptible(mos7840_port->delta_msr_wait, +- (mos7840_port-> ++ wait_event_interruptible(port->delta_msr_wait, ++ (port->serial->disconnected || ++ mos7840_port-> + delta_msr_cond == 1)); + + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; ++ ++ if (port->serial->disconnected) ++ return -EIO; ++ + cnow = mos7840_port->icount; + smp_rmb(); + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && diff --git a/queue-3.8/usb-oti6858-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-oti6858-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..4682754ddd8 --- /dev/null +++ b/queue-3.8/usb-oti6858-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,66 @@ +From 8edfdab37157d2683e51b8be5d3d5697f66a9f7b Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:21 +0100 +Subject: USB: oti6858: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit 8edfdab37157d2683e51b8be5d3d5697f66a9f7b upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/oti6858.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/usb/serial/oti6858.c ++++ b/drivers/usb/serial/oti6858.c +@@ -188,7 +188,6 @@ struct oti6858_private { + u8 setup_done; + struct delayed_work delayed_setup_work; + +- wait_queue_head_t intr_wait; + struct usb_serial_port *port; /* USB port with which associated */ + }; + +@@ -339,7 +338,6 @@ static int oti6858_port_probe(struct usb + return -ENOMEM; + + spin_lock_init(&priv->lock); +- init_waitqueue_head(&priv->intr_wait); + priv->port = port; + INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line); + INIT_DELAYED_WORK(&priv->delayed_write_work, send_data); +@@ -664,11 +662,15 @@ static int wait_modem_info(struct usb_se + spin_unlock_irqrestore(&priv->lock, flags); + + while (1) { +- wait_event_interruptible(priv->intr_wait, ++ wait_event_interruptible(port->delta_msr_wait, ++ port->serial->disconnected || + priv->status.pin_state != prev); + if (signal_pending(current)) + return -ERESTARTSYS; + ++ if (port->serial->disconnected) ++ return -EIO; ++ + spin_lock_irqsave(&priv->lock, flags); + status = priv->status.pin_state & PIN_MASK; + spin_unlock_irqrestore(&priv->lock, flags); +@@ -763,7 +765,7 @@ static void oti6858_read_int_callback(st + + if (!priv->transient) { + if (xs->pin_state != priv->status.pin_state) +- wake_up_interruptible(&priv->intr_wait); ++ wake_up_interruptible(&port->delta_msr_wait); + memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE); + } + diff --git a/queue-3.8/usb-pl2303-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-pl2303-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..5522eeb86c1 --- /dev/null +++ b/queue-3.8/usb-pl2303-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,74 @@ +From 40509ca982c00c4b70fc00be887509feca0bff15 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:22 +0100 +Subject: USB: pl2303: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit 40509ca982c00c4b70fc00be887509feca0bff15 upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/pl2303.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- a/drivers/usb/serial/pl2303.c ++++ b/drivers/usb/serial/pl2303.c +@@ -139,7 +139,6 @@ struct pl2303_serial_private { + + struct pl2303_private { + spinlock_t lock; +- wait_queue_head_t delta_msr_wait; + u8 line_control; + u8 line_status; + }; +@@ -233,7 +232,6 @@ static int pl2303_port_probe(struct usb_ + return -ENOMEM; + + spin_lock_init(&priv->lock); +- init_waitqueue_head(&priv->delta_msr_wait); + + usb_set_serial_port_data(port, priv); + +@@ -607,11 +605,14 @@ static int wait_modem_info(struct usb_se + spin_unlock_irqrestore(&priv->lock, flags); + + while (1) { +- interruptible_sleep_on(&priv->delta_msr_wait); ++ interruptible_sleep_on(&port->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; + ++ if (port->serial->disconnected) ++ return -EIO; ++ + spin_lock_irqsave(&priv->lock, flags); + status = priv->line_status; + spin_unlock_irqrestore(&priv->lock, flags); +@@ -719,7 +720,7 @@ static void pl2303_update_line_status(st + spin_unlock_irqrestore(&priv->lock, flags); + if (priv->line_status & UART_BREAK_ERROR) + usb_serial_handle_break(port); +- wake_up_interruptible(&priv->delta_msr_wait); ++ wake_up_interruptible(&port->delta_msr_wait); + + tty = tty_port_tty_get(&port->port); + if (!tty) +@@ -784,7 +785,7 @@ static void pl2303_process_read_urb(stru + line_status = priv->line_status; + priv->line_status &= ~UART_STATE_TRANSIENT_MASK; + spin_unlock_irqrestore(&priv->lock, flags); +- wake_up_interruptible(&priv->delta_msr_wait); ++ wake_up_interruptible(&port->delta_msr_wait); + + if (!urb->actual_length) + return; diff --git a/queue-3.8/usb-quatech2-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-quatech2-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..8ec558dbd15 --- /dev/null +++ b/queue-3.8/usb-quatech2-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,71 @@ +From 69f87f40d2b98e8b4ab82a121fd2bd584690b887 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:23 +0100 +Subject: USB: quatech2: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit 69f87f40d2b98e8b4ab82a121fd2bd584690b887 upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/quatech2.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/usb/serial/quatech2.c ++++ b/drivers/usb/serial/quatech2.c +@@ -128,7 +128,6 @@ struct qt2_port_private { + u8 shadowLSR; + u8 shadowMSR; + +- wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ + struct async_icount icount; + + struct usb_serial_port *port; +@@ -506,8 +505,9 @@ static int wait_modem_info(struct usb_se + spin_unlock_irqrestore(&priv->lock, flags); + + while (1) { +- wait_event_interruptible(priv->delta_msr_wait, +- ((priv->icount.rng != prev.rng) || ++ wait_event_interruptible(port->delta_msr_wait, ++ (port->serial->disconnected || ++ (priv->icount.rng != prev.rng) || + (priv->icount.dsr != prev.dsr) || + (priv->icount.dcd != prev.dcd) || + (priv->icount.cts != prev.cts))); +@@ -515,6 +515,9 @@ static int wait_modem_info(struct usb_se + if (signal_pending(current)) + return -ERESTARTSYS; + ++ if (port->serial->disconnected) ++ return -EIO; ++ + spin_lock_irqsave(&priv->lock, flags); + cur = priv->icount; + spin_unlock_irqrestore(&priv->lock, flags); +@@ -841,7 +844,6 @@ static int qt2_port_probe(struct usb_ser + + spin_lock_init(&port_priv->lock); + spin_lock_init(&port_priv->urb_lock); +- init_waitqueue_head(&port_priv->delta_msr_wait); + port_priv->port = port; + + port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); +@@ -984,7 +986,7 @@ static void qt2_update_msr(struct usb_se + if (newMSR & UART_MSR_TERI) + port_priv->icount.rng++; + +- wake_up_interruptible(&port_priv->delta_msr_wait); ++ wake_up_interruptible(&port->delta_msr_wait); + } + } + diff --git a/queue-3.8/usb-spcp8x5-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-spcp8x5-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..a85ee8ed767 --- /dev/null +++ b/queue-3.8/usb-spcp8x5-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,66 @@ +From dbcea7615d8d7d58f6ff49d2c5568113f70effe9 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:24 +0100 +Subject: USB: spcp8x5: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit dbcea7615d8d7d58f6ff49d2c5568113f70effe9 upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/spcp8x5.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/usb/serial/spcp8x5.c ++++ b/drivers/usb/serial/spcp8x5.c +@@ -149,7 +149,6 @@ enum spcp8x5_type { + struct spcp8x5_private { + spinlock_t lock; + enum spcp8x5_type type; +- wait_queue_head_t delta_msr_wait; + u8 line_control; + u8 line_status; + }; +@@ -179,7 +178,6 @@ static int spcp8x5_port_probe(struct usb + return -ENOMEM; + + spin_lock_init(&priv->lock); +- init_waitqueue_head(&priv->delta_msr_wait); + priv->type = type; + + usb_set_serial_port_data(port , priv); +@@ -476,7 +474,7 @@ static void spcp8x5_process_read_urb(str + priv->line_status &= ~UART_STATE_TRANSIENT_MASK; + spin_unlock_irqrestore(&priv->lock, flags); + /* wake up the wait for termios */ +- wake_up_interruptible(&priv->delta_msr_wait); ++ wake_up_interruptible(&port->delta_msr_wait); + + if (!urb->actual_length) + return; +@@ -526,12 +524,15 @@ static int spcp8x5_wait_modem_info(struc + + while (1) { + /* wake up in bulk read */ +- interruptible_sleep_on(&priv->delta_msr_wait); ++ interruptible_sleep_on(&port->delta_msr_wait); + + /* see if a signal did it */ + if (signal_pending(current)) + return -ERESTARTSYS; + ++ if (port->serial->disconnected) ++ return -EIO; ++ + spin_lock_irqsave(&priv->lock, flags); + status = priv->line_status; + spin_unlock_irqrestore(&priv->lock, flags); diff --git a/queue-3.8/usb-ssu100-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-ssu100-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..d3ec81b498f --- /dev/null +++ b/queue-3.8/usb-ssu100-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,71 @@ +From 43a66b4c417ad15f6d2f632ce67ad195bdf999e8 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:25 +0100 +Subject: USB: ssu100: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit 43a66b4c417ad15f6d2f632ce67ad195bdf999e8 upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ssu100.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/usb/serial/ssu100.c ++++ b/drivers/usb/serial/ssu100.c +@@ -61,7 +61,6 @@ struct ssu100_port_private { + spinlock_t status_lock; + u8 shadowLSR; + u8 shadowMSR; +- wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ + struct async_icount icount; + }; + +@@ -355,8 +354,9 @@ static int wait_modem_info(struct usb_se + spin_unlock_irqrestore(&priv->status_lock, flags); + + while (1) { +- wait_event_interruptible(priv->delta_msr_wait, +- ((priv->icount.rng != prev.rng) || ++ wait_event_interruptible(port->delta_msr_wait, ++ (port->serial->disconnected || ++ (priv->icount.rng != prev.rng) || + (priv->icount.dsr != prev.dsr) || + (priv->icount.dcd != prev.dcd) || + (priv->icount.cts != prev.cts))); +@@ -364,6 +364,9 @@ static int wait_modem_info(struct usb_se + if (signal_pending(current)) + return -ERESTARTSYS; + ++ if (port->serial->disconnected) ++ return -EIO; ++ + spin_lock_irqsave(&priv->status_lock, flags); + cur = priv->icount; + spin_unlock_irqrestore(&priv->status_lock, flags); +@@ -445,7 +448,6 @@ static int ssu100_port_probe(struct usb_ + return -ENOMEM; + + spin_lock_init(&priv->status_lock); +- init_waitqueue_head(&priv->delta_msr_wait); + + usb_set_serial_port_data(port, priv); + +@@ -537,7 +539,7 @@ static void ssu100_update_msr(struct usb + priv->icount.dcd++; + if (msr & UART_MSR_TERI) + priv->icount.rng++; +- wake_up_interruptible(&priv->delta_msr_wait); ++ wake_up_interruptible(&port->delta_msr_wait); + } + } + diff --git a/queue-3.8/usb-ti_usb_3410_5052-fix-use-after-free-in-tiocmiwait.patch b/queue-3.8/usb-ti_usb_3410_5052-fix-use-after-free-in-tiocmiwait.patch new file mode 100644 index 00000000000..a9ce3d3cb40 --- /dev/null +++ b/queue-3.8/usb-ti_usb_3410_5052-fix-use-after-free-in-tiocmiwait.patch @@ -0,0 +1,64 @@ +From fc98ab873aa3dbe783ce56a2ffdbbe7c7609521a Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 19 Mar 2013 09:21:26 +0100 +Subject: USB: ti_usb_3410_5052: fix use-after-free in TIOCMIWAIT + +From: Johan Hovold + +commit fc98ab873aa3dbe783ce56a2ffdbbe7c7609521a upstream. + +Use the port wait queue and make sure to check the serial disconnected +flag before accessing private port data after waking up. + +This is is needed as the private port data (including the wait queue +itself) can be gone when waking up after a disconnect. + +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ti_usb_3410_5052.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -74,7 +74,6 @@ struct ti_port { + int tp_flags; + int tp_closing_wait;/* in .01 secs */ + struct async_icount tp_icount; +- wait_queue_head_t tp_msr_wait; /* wait for msr change */ + wait_queue_head_t tp_write_wait; + struct ti_device *tp_tdev; + struct usb_serial_port *tp_port; +@@ -432,7 +431,6 @@ static int ti_port_probe(struct usb_seri + else + tport->tp_uart_base_addr = TI_UART2_BASE_ADDR; + tport->tp_closing_wait = closing_wait; +- init_waitqueue_head(&tport->tp_msr_wait); + init_waitqueue_head(&tport->tp_write_wait); + if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, GFP_KERNEL)) { + kfree(tport); +@@ -784,9 +782,13 @@ static int ti_ioctl(struct tty_struct *t + dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__); + cprev = tport->tp_icount; + while (1) { +- interruptible_sleep_on(&tport->tp_msr_wait); ++ interruptible_sleep_on(&port->delta_msr_wait); + if (signal_pending(current)) + return -ERESTARTSYS; ++ ++ if (port->serial->disconnected) ++ return -EIO; ++ + cnow = tport->tp_icount; + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) +@@ -1400,7 +1402,7 @@ static void ti_handle_new_msr(struct ti_ + icount->dcd++; + if (msr & TI_MSR_DELTA_RI) + icount->rng++; +- wake_up_interruptible(&tport->tp_msr_wait); ++ wake_up_interruptible(&tport->tp_port->delta_msr_wait); + spin_unlock_irqrestore(&tport->tp_lock, flags); + } + -- 2.47.3