Skip to content

Commit

Permalink
tty: Redo current tty locking
Browse files Browse the repository at this point in the history
Currently it is sometimes locked by the tty mutex and sometimes by the
sighand lock. The latter is in fact correct and now we can hand back referenced
objects we can fix this up without problems around sleeping functions.

Signed-off-by: Alan Cox <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Alan Cox authored and torvalds committed Oct 13, 2008
1 parent 2cb5998 commit 934e6eb
Show file tree
Hide file tree
Showing 4 changed files with 5 additions and 18 deletions.
18 changes: 4 additions & 14 deletions drivers/char/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -739,13 +739,11 @@ void tty_vhangup_self(void)
{
struct tty_struct *tty;

mutex_lock(&tty_mutex);
tty = get_current_tty();
if (tty) {
tty_vhangup(tty);
tty_kref_put(tty);
}
mutex_unlock(&tty_mutex);
}

/**
Expand Down Expand Up @@ -801,11 +799,9 @@ void disassociate_ctty(int on_exit)
struct pid *tty_pgrp = NULL;


mutex_lock(&tty_mutex);
tty = get_current_tty();
if (tty) {
tty_pgrp = get_pid(tty->pgrp);
mutex_unlock(&tty_mutex);
lock_kernel();
if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
tty_vhangup(tty);
Expand All @@ -822,7 +818,6 @@ void disassociate_ctty(int on_exit)
kill_pgrp(old_pgrp, SIGCONT, on_exit);
put_pid(old_pgrp);
}
mutex_unlock(&tty_mutex);
return;
}
if (tty_pgrp) {
Expand All @@ -837,7 +832,6 @@ void disassociate_ctty(int on_exit)
current->signal->tty_old_pgrp = NULL;
spin_unlock_irq(&current->sighand->siglock);

mutex_lock(&tty_mutex);
tty = get_current_tty();
if (tty) {
unsigned long flags;
Expand All @@ -854,7 +848,6 @@ void disassociate_ctty(int on_exit)
" = NULL", tty);
#endif
}
mutex_unlock(&tty_mutex);

/* Now clear signal->tty under the lock */
read_lock(&tasklist_lock);
Expand Down Expand Up @@ -3180,14 +3173,11 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
struct tty_struct *get_current_tty(void)
{
struct tty_struct *tty;
WARN_ON_ONCE(!mutex_is_locked(&tty_mutex));
unsigned long flags;

spin_lock_irqsave(&current->sighand->siglock, flags);
tty = tty_kref_get(current->signal->tty);
/*
* session->tty can be changed/cleared from under us, make sure we
* issue the load. The obtained pointer, when not NULL, is valid as
* long as we hold tty_mutex.
*/
barrier();
spin_unlock_irqrestore(&current->sighand->siglock, flags);
return tty;
}
EXPORT_SYMBOL_GPL(get_current_tty);
Expand Down
1 change: 1 addition & 0 deletions drivers/s390/char/fs3270.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ fs3270_open(struct inode *inode, struct file *filp)
tty = get_current_tty();
if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) {
tty_kref_put(tty);
mutex_unlock(&tty_mutex);
rc = -ENODEV;
goto out;
}
Expand Down
2 changes: 0 additions & 2 deletions fs/dquot.c
Original file line number Diff line number Diff line change
Expand Up @@ -895,9 +895,7 @@ static void print_warning(struct dquot *dquot, const int warntype)
warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot))
return;

mutex_lock(&tty_mutex);
tty = get_current_tty();
mutex_unlock(&tty_mutex);
if (!tty)
return;
tty_write_message(tty, dquot->dq_sb->s_id);
Expand Down
2 changes: 0 additions & 2 deletions security/selinux/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -2121,9 +2121,7 @@ static inline void flush_unauthorized_files(struct files_struct *files)
long j = -1;
int drop_tty = 0;

mutex_lock(&tty_mutex);
tty = get_current_tty();
mutex_unlock(&tty_mutex);
if (tty) {
file_list_lock();
file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list);
Expand Down

0 comments on commit 934e6eb

Please sign in to comment.