Commit 32a4bf2e81ec378e5925d4e069e0677a6c86a6ad
1 parent
d269d4434c
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
USB: console: fix potential use after free
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") Cc: stable <stable@vger.kernel.org> Signed-off-by: Johan Hovold <johan@kernel.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); |