diff options
| author | Peter Hurley <peter@hurleysoftware.com> | 2013-06-13 15:56:37 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-06-17 15:37:29 -0400 |
| commit | 7c61c3d8f44d5d822f758754287af644307b4af9 (patch) | |
| tree | bc874566194bc82c269c565641f0829983192c85 | |
| parent | ef223fb3d1d61c2a95a89cdc02f8e86dac96ddc3 (diff) | |
tty: Fix transient pty write() EIO
Commit 699390354da6c258b65bf8fa79cfd5feaede50b6
('pty: Ignore slave pty close() if never successfully opened')
introduced a bug with ptys whereby a write() in parallel with an
open() on an existing pty could mistakenly indicate an I/O error.
Only indicate an I/O error if the condition on open() actually exists.
Reported-by: Markus Trippelsdorf <markus@trippelsdorf.de>
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Tested-by: Mikael Pettersson <mikpe@it.uu.se>
Cc: stable <stable@vger.kernel.org> # 3.9
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/tty/pty.c | 13 |
1 files changed, 5 insertions, 8 deletions
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 59bfaecc4e14..abfd99089781 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
| @@ -244,14 +244,9 @@ static void pty_flush_buffer(struct tty_struct *tty) | |||
| 244 | 244 | ||
| 245 | static int pty_open(struct tty_struct *tty, struct file *filp) | 245 | static int pty_open(struct tty_struct *tty, struct file *filp) |
| 246 | { | 246 | { |
| 247 | int retval = -ENODEV; | ||
| 248 | |||
| 249 | if (!tty || !tty->link) | 247 | if (!tty || !tty->link) |
| 250 | goto out; | 248 | return -ENODEV; |
| 251 | |||
| 252 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
| 253 | 249 | ||
| 254 | retval = -EIO; | ||
| 255 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) | 250 | if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) |
| 256 | goto out; | 251 | goto out; |
| 257 | if (test_bit(TTY_PTY_LOCK, &tty->link->flags)) | 252 | if (test_bit(TTY_PTY_LOCK, &tty->link->flags)) |
| @@ -262,9 +257,11 @@ static int pty_open(struct tty_struct *tty, struct file *filp) | |||
| 262 | clear_bit(TTY_IO_ERROR, &tty->flags); | 257 | clear_bit(TTY_IO_ERROR, &tty->flags); |
| 263 | clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); | 258 | clear_bit(TTY_OTHER_CLOSED, &tty->link->flags); |
| 264 | set_bit(TTY_THROTTLED, &tty->flags); | 259 | set_bit(TTY_THROTTLED, &tty->flags); |
| 265 | retval = 0; | 260 | return 0; |
| 261 | |||
| 266 | out: | 262 | out: |
| 267 | return retval; | 263 | set_bit(TTY_IO_ERROR, &tty->flags); |
| 264 | return -EIO; | ||
| 268 | } | 265 | } |
| 269 | 266 | ||
| 270 | static void pty_set_termios(struct tty_struct *tty, | 267 | static void pty_set_termios(struct tty_struct *tty, |
