Skip to content

Commit 7f22f6c

Browse files
peterhurleygregkh
authored andcommitted
tty: Retry failed reopen if tty teardown in-progress
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>
1 parent 0bfd464 commit 7f22f6c

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

drivers/tty/tty_io.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,13 +1463,13 @@ static int tty_reopen(struct tty_struct *tty)
14631463
{
14641464
struct tty_driver *driver = tty->driver;
14651465

1466-
if (!tty->count)
1467-
return -EIO;
1468-
14691466
if (driver->type == TTY_DRIVER_TYPE_PTY &&
14701467
driver->subtype == PTY_TYPE_MASTER)
14711468
return -EIO;
14721469

1470+
if (!tty->count)
1471+
return -EAGAIN;
1472+
14731473
if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN))
14741474
return -EBUSY;
14751475

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

20892089
if (IS_ERR(tty)) {
20902090
retval = PTR_ERR(tty);
2091-
goto err_file;
2091+
if (retval != -EAGAIN || signal_pending(current))
2092+
goto err_file;
2093+
tty_free_file(filp);
2094+
schedule();
2095+
goto retry_open;
20922096
}
20932097

20942098
tty_add_file(tty, filp);

0 commit comments

Comments
 (0)