Skip to content

Commit

Permalink
tty: Drop krefs for interrupted tty lock
Browse files Browse the repository at this point in the history
When the tty lock is interrupted on attempted re-open, 2 tty krefs
are still held. Drop extra kref before returning failure from
tty_lock_interruptible(), and drop lookup kref before returning
failure from tty_open().

Fixes: 0bfd464 ("tty: Wait interruptibly for tty lock on reopen")
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Peter Hurley authored and Greg Kroah-Hartman committed Feb 7, 2016
1 parent 36f90b0 commit e9036d0
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 3 deletions.
3 changes: 1 addition & 2 deletions drivers/tty/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -2066,13 +2066,12 @@ static int tty_open(struct inode *inode, struct file *filp)
if (tty) {
mutex_unlock(&tty_mutex);
retval = tty_lock_interruptible(tty);
tty_kref_put(tty); /* drop kref from tty_driver_lookup_tty() */
if (retval) {
if (retval == -EINTR)
retval = -ERESTARTSYS;
goto err_unref;
}
/* safe to drop the kref from tty_driver_lookup_tty() */
tty_kref_put(tty);
retval = tty_reopen(tty);
if (retval < 0) {
tty_unlock(tty);
Expand Down
7 changes: 6 additions & 1 deletion drivers/tty/tty_mutex.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@ EXPORT_SYMBOL(tty_lock);

int tty_lock_interruptible(struct tty_struct *tty)
{
int ret;

if (WARN(tty->magic != TTY_MAGIC, "L Bad %p\n", tty))
return -EIO;
tty_kref_get(tty);
return mutex_lock_interruptible(&tty->legacy_mutex);
ret = mutex_lock_interruptible(&tty->legacy_mutex);
if (ret)
tty_kref_put(tty);
return ret;
}

void __lockfunc tty_unlock(struct tty_struct *tty)
Expand Down

0 comments on commit e9036d0

Please sign in to comment.