TTY: ldisc, wait for idle ldisc in release
We reintroduced tty_ldisc_wait_idle in100eeae2c5
(TTY: restore tty_ldisc_wait_idle) and used in set_ldisc. Then we added it also to the hangup path in92f6fa09bd
(TTY: ldisc, do not close until there are readers). And we noted that there is one more path: ~ Before65b770468e
tty_ldisc_wait_idle was called also from ~ tty_ldisc_release. It is called from tty_release, so I don't think ~ we need to restore that one. Well, I was wrong. There might still be holders of an ldisc reference. Not from userspace, but drivers. If they take a reference and a user closes the device immediately after that, we have a problem. ldisc is halted and closed by TTY, but the driver still may call some ldisc's operation and cause a crash. So restore the tty_ldisc_wait_idle call also to the third location where it was before65b770468e
(tty-ldisc: turn ldisc user count into a proper refcount). Now we should be safe with respect to the ldisc reference counting as all* tty_ldisc_close paths are safely called with reference count of one. * Not the one in tty_ldisc_setup's fail path. But that is called before the first open finishes. So userspace does not see it yet. Even thought the driver is given the TTY already via ->install, it should not take a reference to the ldisc yet. If some driver is to do this, we should put one tty_ldisc_wait_idle also in the setup. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Acked-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
7ee00fdb16
commit
31e121284f
|
@ -897,6 +897,11 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
|
|||
|
||||
static void tty_ldisc_kill(struct tty_struct *tty)
|
||||
{
|
||||
/* There cannot be users from userspace now. But there still might be
|
||||
* drivers holding a reference via tty_ldisc_ref. Do not steal them the
|
||||
* ldisc until they are done. */
|
||||
tty_ldisc_wait_idle(tty, MAX_SCHEDULE_TIMEOUT);
|
||||
|
||||
mutex_lock(&tty->ldisc_mutex);
|
||||
/*
|
||||
* Now kill off the ldisc
|
||||
|
|
Loading…
Reference in New Issue