summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2016-01-09 21:45:11 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-01-28 11:58:02 -0800
commita8f3a29718f77df3116955d100756f67fafabec0 (patch)
tree435e824fef69ff9d08e6df6baf06fde5a31c2b5e /drivers
parentf557474ca3a23800dffb790846bcb121fa046c71 (diff)
tty: Fix ioctl(FIOASYNC) on hungup file
A small race window exists which allows signal-driven async i/o to be enabled for the tty when the file ptr has already been hungup and signal-driven i/o has been disabled: CPU 0 CPU 1 ----- ------ ioctl_fioasync(on) filp->f_op->fasync(on) __tty_hangup() tty_fasync(on) tty_lock() tty_lock() ... . filp->f_op = &hung_up_tty_fops; (waiting) __tty_fasync(off) . tty_unlock() /* gets tty lock */ /* enables FASYNC */ Check the tty has not been hungup while holding tty_lock. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/tty/tty_io.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 0140c8669ada..8d26ed79bb4c 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -2260,10 +2260,11 @@ out:
static int tty_fasync(int fd, struct file *filp, int on)
{
struct tty_struct *tty = file_tty(filp);
- int retval;
+ int retval = -ENOTTY;
tty_lock(tty);
- retval = __tty_fasync(fd, filp, on);
+ if (!tty_hung_up_p(filp))
+ retval = __tty_fasync(fd, filp, on);
tty_unlock(tty);
return retval;