hso: update serial_table in usb disconnect method
The serial_table is used to map the minor number of the usb serial device to its associated context. The table is updated in the probe method and in hso_serial_ref_free() which is called either from the tty cleanup method or from the usb disconnect method. This patch ensures that the serial_table is updated in the disconnect method and no more from the cleanup method to avoid the following potential race condition. - hso_disconnect() is called for usb interface "x". Because the serial port was open and because the cleanup method of the tty_port hasn't been called yet, hso_serial_ref_free() is not run. - hso_probe() is called and fails for a new hso serial usb interface "y". The function hso_free_interface() is called and iterates over the element of serial_table to find the device associated to the usb interface context. If the usb interface context of usb interface "y" has been created at the same place as for usb interface "x", then the cleanup functions are called for usb interfaces "x" and "y" and hso_serial_ref_free() is called for both interfaces. - release_tty() is called for serial port linked to usb interface "x" and possibly crash because the tty_port structure contained in the hso_device structure has been freed. Signed-off-by: Olivier Sobrie <olivier@sobrie.be> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
69b377b31b
commit
301d3b7e10
|
@ -2597,7 +2597,6 @@ static void hso_free_serial_device(struct hso_device *hso_dev)
|
|||
|
||||
if (!serial)
|
||||
return;
|
||||
set_serial_by_index(serial->minor, NULL);
|
||||
|
||||
hso_serial_common_free(serial);
|
||||
|
||||
|
@ -3109,6 +3108,7 @@ static void hso_free_interface(struct usb_interface *interface)
|
|||
mutex_unlock(&serial->parent->mutex);
|
||||
hso_serial_tty_unregister(serial);
|
||||
kref_put(&serial_table[i]->ref, hso_serial_ref_free);
|
||||
set_serial_by_index(i, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue