Commit 72934919ba0f17b51166e5ab31c52e114676cb25

Authored by Johan Hovold
Committed by Greg Kroah-Hartman
1 parent 68d91b4c79

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 1 changed file with 10 additions and 5 deletions Side-by-side Diff

drivers/usb/serial/console.c
... ... @@ -46,6 +46,8 @@
46 46 * ------------------------------------------------------------
47 47 */
48 48  
  49 +static const struct tty_operations usb_console_fake_tty_ops = {
  50 +};
49 51  
50 52 /*
51 53 * The parsing of the command line works exactly like the
52 54  
53 55  
54 56  
... ... @@ -137,14 +139,17 @@
137 139 goto reset_open_count;
138 140 }
139 141 kref_init(&tty->kref);
140   - tty_port_tty_set(&port->port, tty);
141 142 tty->driver = usb_serial_tty_driver;
142 143 tty->index = co->index;
143 144 init_ldsem(&tty->ldisc_sem);
  145 + INIT_LIST_HEAD(&tty->tty_files);
  146 + kref_get(&tty->driver->kref);
  147 + tty->ops = &usb_console_fake_tty_ops;
144 148 if (tty_init_termios(tty)) {
145 149 retval = -ENOMEM;
146   - goto free_tty;
  150 + goto put_tty;
147 151 }
  152 + tty_port_tty_set(&port->port, tty);
148 153 }
149 154  
150 155 /* only call the device specific open if this
... ... @@ -162,7 +167,7 @@
162 167 serial->type->set_termios(tty, port, &dummy);
163 168  
164 169 tty_port_tty_set(&port->port, NULL);
165   - kfree(tty);
  170 + tty_kref_put(tty);
166 171 }
167 172 set_bit(ASYNCB_INITIALIZED, &port->port.flags);
168 173 }
... ... @@ -178,8 +183,8 @@
178 183  
179 184 fail:
180 185 tty_port_tty_set(&port->port, NULL);
181   - free_tty:
182   - kfree(tty);
  186 + put_tty:
  187 + tty_kref_put(tty);
183 188 reset_open_count:
184 189 port->port.count = 0;
185 190 usb_autopm_put_interface(serial->interface);