Skip to content

Commit

Permalink
tty: Retry failed reopen if tty teardown in-progress
Browse files Browse the repository at this point in the history
A small window exists where a tty reopen will observe the tty
just prior to imminent teardown (tty->count == 0); in this case, open()
returns EIO to userspace.

Instead, retry the open after checking for signals and yielding;
this interruptible retry loop allows teardown to commence and initialize
a new tty on retry. Never retry the BSD master pty reopen; there is no
guarantee the pty pair teardown is imminent since the slave file
descriptors may remain open indefinitely.

Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Cc: stable <stable@vger.kernel.org> # 4.4
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Peter Hurley authored and Greg Kroah-Hartman committed Jan 27, 2016
1 parent 0bfd464 commit 7f22f6c
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions drivers/tty/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1463,13 +1463,13 @@ static int tty_reopen(struct tty_struct *tty)
{
struct tty_driver *driver = tty->driver;

if (!tty->count)
return -EIO;

if (driver->type == TTY_DRIVER_TYPE_PTY &&
driver->subtype == PTY_TYPE_MASTER)
return -EIO;

if (!tty->count)
return -EAGAIN;

if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN))
return -EBUSY;

Expand Down Expand Up @@ -2088,7 +2088,11 @@ static int tty_open(struct inode *inode, struct file *filp)

if (IS_ERR(tty)) {
retval = PTR_ERR(tty);
goto err_file;
if (retval != -EAGAIN || signal_pending(current))
goto err_file;
tty_free_file(filp);
schedule();
goto retry_open;
}

tty_add_file(tty, filp);
Expand Down

0 comments on commit 7f22f6c

Please sign in to comment.