| From 9e88e8b9915b5e067507a087437d80e6a133d612 Mon Sep 17 00:00:00 2001 |
| From: Jiri Slaby <jslaby@suse.cz> |
| Date: Sat, 27 Nov 2010 16:06:46 +0100 |
| Subject: [PATCH 1/1] TTY: open/hangup race fixup |
| |
| |
| Signed-off-by: Jiri Slaby <jslaby@suse.cz> |
| |
| drivers/tty/tty_io.c | 10 +++++++++- |
| include/linux/tty.h | 1 + |
| 2 files changed, 10 insertions(+), 1 deletions(-) |
| |
| diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c |
| index 878f6d6..35480dd 100644 |
| |
| |
| @@ -559,6 +559,9 @@ void __tty_hangup(struct tty_struct *tty) |
| |
| tty_lock(); |
| |
| + /* some functions below drop BTM, so we need this bit */ |
| + set_bit(TTY_HUPPING, &tty->flags); |
| + |
| /* inuse_filps is protected by the single tty lock, |
| this really needs to change if we want to flush the |
| workqueue with the lock held */ |
| @@ -578,6 +581,10 @@ void __tty_hangup(struct tty_struct *tty) |
| } |
| spin_unlock(&tty_files_lock); |
| |
| + /* |
| + * it drops BTM and thus races with reopen |
| + * we protect the race by TTY_HUPPING |
| + */ |
| tty_ldisc_hangup(tty); |
| |
| read_lock(&tasklist_lock); |
| @@ -615,7 +622,6 @@ void __tty_hangup(struct tty_struct *tty) |
| tty->session = NULL; |
| tty->pgrp = NULL; |
| tty->ctrl_status = 0; |
| - set_bit(TTY_HUPPED, &tty->flags); |
| spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
| |
| /* Account for the p->signal references we killed */ |
| @@ -641,6 +647,7 @@ void __tty_hangup(struct tty_struct *tty) |
| * can't yet guarantee all that. |
| */ |
| set_bit(TTY_HUPPED, &tty->flags); |
| + clear_bit(TTY_HUPPING, &tty->flags); |
| tty_ldisc_enable(tty); |
| |
| tty_unlock(); |
| @@ -1311,6 +1318,7 @@ static int tty_reopen(struct tty_struct *tty) |
| struct tty_driver *driver = tty->driver; |
| |
| if (test_bit(TTY_CLOSING, &tty->flags) || |
| + test_bit(TTY_HUPPING, &tty->flags) || |
| test_bit(TTY_LDISC_CHANGING, &tty->flags)) |
| return -EIO; |
| |
| diff --git a/include/linux/tty.h b/include/linux/tty.h |
| index 032d79f..54e4eaa 100644 |
| |
| |
| @@ -366,6 +366,7 @@ struct tty_file_private { |
| #define TTY_HUPPED 18 /* Post driver->hangup() */ |
| #define TTY_FLUSHING 19 /* Flushing to ldisc in progress */ |
| #define TTY_FLUSHPENDING 20 /* Queued buffer flush pending */ |
| +#define TTY_HUPPING 21 /* ->hangup() in progress */ |
| |
| #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) |
| |
| -- |
| 1.7.3.1 |
| |