aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-10-13 05:40:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 12:51:41 -0400
commit934e6ebf96e8c1a0f299e64129fdaebc1132a427 (patch)
treeab4bd754997b097f06a5cfefd9e3671d56e628f4
parent2cb5998b5f0ccc886fdda3509059eef297b49577 (diff)
tty: Redo current tty locking
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 <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/char/tty_io.c18
-rw-r--r--drivers/s390/char/fs3270.c1
-rw-r--r--fs/dquot.c2
-rw-r--r--security/selinux/hooks.c2
4 files changed, 5 insertions, 18 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index b5f57d0b30ee..f40298e9873a 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -739,13 +739,11 @@ void tty_vhangup_self(void)
739{ 739{
740 struct tty_struct *tty; 740 struct tty_struct *tty;
741 741
742 mutex_lock(&tty_mutex);
743 tty = get_current_tty(); 742 tty = get_current_tty();
744 if (tty) { 743 if (tty) {
745 tty_vhangup(tty); 744 tty_vhangup(tty);
746 tty_kref_put(tty); 745 tty_kref_put(tty);
747 } 746 }
748 mutex_unlock(&tty_mutex);
749} 747}
750 748
751/** 749/**
@@ -801,11 +799,9 @@ void disassociate_ctty(int on_exit)
801 struct pid *tty_pgrp = NULL; 799 struct pid *tty_pgrp = NULL;
802 800
803 801
804 mutex_lock(&tty_mutex);
805 tty = get_current_tty(); 802 tty = get_current_tty();
806 if (tty) { 803 if (tty) {
807 tty_pgrp = get_pid(tty->pgrp); 804 tty_pgrp = get_pid(tty->pgrp);
808 mutex_unlock(&tty_mutex);
809 lock_kernel(); 805 lock_kernel();
810 if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) 806 if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
811 tty_vhangup(tty); 807 tty_vhangup(tty);
@@ -822,7 +818,6 @@ void disassociate_ctty(int on_exit)
822 kill_pgrp(old_pgrp, SIGCONT, on_exit); 818 kill_pgrp(old_pgrp, SIGCONT, on_exit);
823 put_pid(old_pgrp); 819 put_pid(old_pgrp);
824 } 820 }
825 mutex_unlock(&tty_mutex);
826 return; 821 return;
827 } 822 }
828 if (tty_pgrp) { 823 if (tty_pgrp) {
@@ -837,7 +832,6 @@ void disassociate_ctty(int on_exit)
837 current->signal->tty_old_pgrp = NULL; 832 current->signal->tty_old_pgrp = NULL;
838 spin_unlock_irq(&current->sighand->siglock); 833 spin_unlock_irq(&current->sighand->siglock);
839 834
840 mutex_lock(&tty_mutex);
841 tty = get_current_tty(); 835 tty = get_current_tty();
842 if (tty) { 836 if (tty) {
843 unsigned long flags; 837 unsigned long flags;
@@ -854,7 +848,6 @@ void disassociate_ctty(int on_exit)
854 " = NULL", tty); 848 " = NULL", tty);
855#endif 849#endif
856 } 850 }
857 mutex_unlock(&tty_mutex);
858 851
859 /* Now clear signal->tty under the lock */ 852 /* Now clear signal->tty under the lock */
860 read_lock(&tasklist_lock); 853 read_lock(&tasklist_lock);
@@ -3180,14 +3173,11 @@ static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
3180struct tty_struct *get_current_tty(void) 3173struct tty_struct *get_current_tty(void)
3181{ 3174{
3182 struct tty_struct *tty; 3175 struct tty_struct *tty;
3183 WARN_ON_ONCE(!mutex_is_locked(&tty_mutex)); 3176 unsigned long flags;
3177
3178 spin_lock_irqsave(&current->sighand->siglock, flags);
3184 tty = tty_kref_get(current->signal->tty); 3179 tty = tty_kref_get(current->signal->tty);
3185 /* 3180 spin_unlock_irqrestore(&current->sighand->siglock, flags);
3186 * session->tty can be changed/cleared from under us, make sure we
3187 * issue the load. The obtained pointer, when not NULL, is valid as
3188 * long as we hold tty_mutex.
3189 */
3190 barrier();
3191 return tty; 3181 return tty;
3192} 3182}
3193EXPORT_SYMBOL_GPL(get_current_tty); 3183EXPORT_SYMBOL_GPL(get_current_tty);
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index 3ef5425d0eb8..84fbc90480dc 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -431,6 +431,7 @@ fs3270_open(struct inode *inode, struct file *filp)
431 tty = get_current_tty(); 431 tty = get_current_tty();
432 if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) { 432 if (!tty || tty->driver->major != IBM_TTY3270_MAJOR) {
433 tty_kref_put(tty); 433 tty_kref_put(tty);
434 mutex_unlock(&tty_mutex);
434 rc = -ENODEV; 435 rc = -ENODEV;
435 goto out; 436 goto out;
436 } 437 }
diff --git a/fs/dquot.c b/fs/dquot.c
index 7417a6ca3129..ad7e59003e04 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -895,9 +895,7 @@ static void print_warning(struct dquot *dquot, const int warntype)
895 warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot)) 895 warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot))
896 return; 896 return;
897 897
898 mutex_lock(&tty_mutex);
899 tty = get_current_tty(); 898 tty = get_current_tty();
900 mutex_unlock(&tty_mutex);
901 if (!tty) 899 if (!tty)
902 return; 900 return;
903 tty_write_message(tty, dquot->dq_sb->s_id); 901 tty_write_message(tty, dquot->dq_sb->s_id);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 089d61a23952..48881394fbd4 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2121,9 +2121,7 @@ static inline void flush_unauthorized_files(struct files_struct *files)
2121 long j = -1; 2121 long j = -1;
2122 int drop_tty = 0; 2122 int drop_tty = 0;
2123 2123
2124 mutex_lock(&tty_mutex);
2125 tty = get_current_tty(); 2124 tty = get_current_tty();
2126 mutex_unlock(&tty_mutex);
2127 if (tty) { 2125 if (tty) {
2128 file_list_lock(); 2126 file_list_lock();
2129 file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list); 2127 file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list);