hso: Fix crashes on close.
authorDenis Joseph Barrow <D.Barow@option.com>
Tue, 25 Nov 2008 08:27:50 +0000 (00:27 -0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 25 Nov 2008 08:27:50 +0000 (00:27 -0800)
Moved serial_open_count in hso_serial_open to
prevent crashes owing to the serial structure being made NULL
when hso_serial_close is called even though hso_serial_open
returned -ENODEV, Alan Cox pointed out this happens,
also put in sanity check in hso_serial_close
to check for a valid serial structure which should prevent
the most reproducable crash in the driver when the hso device
is disconnected while in use.

Signed-off-by: Denis Joseph Barrow <D.Barow@option.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/usb/hso.c

index cee1d2a280bd769af22747f18670054f0f98922c..d5857321979bee719da9713f8cc5a88a1d47b3bb 100644 (file)
@@ -1235,6 +1235,11 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
        }
 
        mutex_lock(&serial->parent->mutex);
+       /* check for port already opened, if not set the termios */
+       /* The serial->open count needs to be here as hso_serial_close
+        *  will be called even if hso_serial_open returns -ENODEV.
+        */
+       serial->open_count++;
        result = usb_autopm_get_interface(serial->parent->interface);
        if (result < 0)
                goto err_out;
@@ -1246,8 +1251,6 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
        tty->driver_data = serial;
        serial->tty = tty;
 
-       /* check for port already opened, if not set the termios */
-       serial->open_count++;
        if (serial->open_count == 1) {
                tty->low_latency = 1;
                serial->rx_state = RX_IDLE;
@@ -1285,6 +1288,10 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
        u8 usb_gone;
 
        D1("Closing serial port");
+       if (serial == NULL || serial->magic != HSO_SERIAL_MAGIC) {
+               D1("invalid serial structure bailing out.\n");
+               return;
+       }
 
        mutex_lock(&serial->parent->mutex);
        usb_gone = serial->parent->usb_gone;