aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/console.c
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2015-01-05 16:04:13 +0100
committerBen Hutchings <ben@decadent.org.uk>2015-02-20 00:49:36 +0000
commit27e5ab9cfb34a9491599c1cc7785755b2c5cb512 (patch)
tree4f7b9ca5b7462a6b76f3090aeb87bdbdeda59dc2 /drivers/usb/serial/console.c
parent06be755d7d93bfd196e41c8d84b234227a155374 (diff)
downloadkernel_samsung_smdk4412-27e5ab9cfb34a9491599c1cc7785755b2c5cb512.zip
kernel_samsung_smdk4412-27e5ab9cfb34a9491599c1cc7785755b2c5cb512.tar.gz
kernel_samsung_smdk4412-27e5ab9cfb34a9491599c1cc7785755b2c5cb512.tar.bz2
USB: console: fix potential use after free
commit 32a4bf2e81ec378e5925d4e069e0677a6c86a6ad upstream. Use tty kref to release the fake tty in usb_console_setup to avoid use after free if the underlying serial driver has acquired a reference. Note that using the tty destructor release_one_tty requires some more state to be initialised. Fixes: 4a90f09b20f4 ("tty: usb-serial krefs") Signed-off-by: Johan Hovold <johan@kernel.org> [bwh: Backported to 3.2: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'drivers/usb/serial/console.c')
-rw-r--r--drivers/usb/serial/console.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 1ee6b2a..87302dd 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -47,6 +47,8 @@ static struct console usbcons;
* ------------------------------------------------------------
*/
+static const struct tty_operations usb_console_fake_tty_ops = {
+};
/*
* The parsing of the command line works exactly like the
@@ -141,14 +143,17 @@ static int usb_console_setup(struct console *co, char *options)
goto reset_open_count;
}
kref_init(&tty->kref);
- tty_port_tty_set(&port->port, tty);
tty->driver = usb_serial_tty_driver;
tty->index = co->index;
+ INIT_LIST_HEAD(&tty->tty_files);
+ kref_get(&tty->driver->kref);
+ tty->ops = &usb_console_fake_tty_ops;
if (tty_init_termios(tty)) {
retval = -ENOMEM;
err("no more memory");
- goto free_tty;
+ goto put_tty;
}
+ tty_port_tty_set(&port->port, tty);
}
/* only call the device specific open if this
@@ -170,7 +175,7 @@ static int usb_console_setup(struct console *co, char *options)
serial->type->set_termios(tty, port, &dummy);
tty_port_tty_set(&port->port, NULL);
- kfree(tty);
+ tty_kref_put(tty);
}
set_bit(ASYNCB_INITIALIZED, &port->port.flags);
}
@@ -186,8 +191,8 @@ static int usb_console_setup(struct console *co, char *options)
fail:
tty_port_tty_set(&port->port, NULL);
- free_tty:
- kfree(tty);
+ put_tty:
+ tty_kref_put(tty);
reset_open_count:
port->port.count = 0;
usb_autopm_put_interface(serial->interface);