diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/tty_io.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 48b59006afcd..635437319778 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -2719,6 +2719,8 @@ static int tty_fasync(int fd, struct file * filp, int on) * Locking: * Called functions take tty_ldisc_lock * current->signal->tty check is safe without locks + * + * FIXME: may race normal receive processing */ static int tiocsti(struct tty_struct *tty, char __user *p) @@ -2878,9 +2880,7 @@ static int fionbio(struct file *file, int __user *p) * Locking: * Takes tasklist lock internally to walk sessions * Takes task_lock() when updating signal->tty - * - * FIXME: tty_mutex is needed to protect signal->tty references. - * FIXME: why task_lock on the signal->tty reference ?? + * Takes tty_mutex() to protect tty instance * */ @@ -2915,9 +2915,11 @@ static int tiocsctty(struct tty_struct *tty, int arg) } else return -EPERM; } + mutex_lock(&tty_mutex); task_lock(current); current->signal->tty = tty; task_unlock(current); + mutex_unlock(&tty_mutex); current->signal->tty_old_pgrp = 0; tty->session = current->signal->session; tty->pgrp = process_group(current); @@ -2957,8 +2959,6 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t * permitted where the tty session is our session. * * Locking: None - * - * FIXME: current->signal->tty referencing is unsafe. */ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) @@ -3037,19 +3037,20 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) * timed break functionality. * * Locking: - * None + * atomic_write_lock serializes * - * FIXME: - * What if two overlap */ static int send_break(struct tty_struct *tty, unsigned int duration) { + if (mutex_lock_interruptible(&tty->atomic_write_lock)) + return -EINTR; tty->driver->break_ctl(tty, -1); if (!signal_pending(current)) { msleep_interruptible(duration); } tty->driver->break_ctl(tty, 0); + mutex_unlock(&tty->atomic_write_lock); if (signal_pending(current)) return -EINTR; return 0; @@ -3142,6 +3143,8 @@ int tty_ioctl(struct inode * inode, struct file * file, if (tty_paranoia_check(tty, inode, "tty_ioctl")) return -EINVAL; + /* CHECKME: is this safe as one end closes ? */ + real_tty = tty; if (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER) |