aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-10-13 05:39:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 12:51:41 -0400
commit452a00d2ee288f2cbc36f676edd06cb14d2878c1 (patch)
treec8251c73924a6ac9b174bc557357bfeff0c8d1a8
parentf4d2a6c2096b764decb20070b1bf4356de9144a8 (diff)
tty: Make get_current_tty use a kref
We now return a kref covered tty reference. That ensures the tty structure doesn't go away when you have a return from get_current_tty. This is not enough to protect you from most of the resources being freed behind your back - yet. [Updated to include fixes for SELinux problems found by Andrew Morton and an s390 leak found while debugging the former] Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/char/tty_io.c10
-rw-r--r--drivers/s390/char/fs3270.c3
-rw-r--r--fs/dquot.c6
-rw-r--r--security/selinux/hooks.c3
4 files changed, 13 insertions, 9 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 9a76db3cda1c..4c0e4ed31a48 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -786,12 +786,12 @@ void disassociate_ctty(int on_exit)
786 tty = get_current_tty(); 786 tty = get_current_tty();
787 if (tty) { 787 if (tty) {
788 tty_pgrp = get_pid(tty->pgrp); 788 tty_pgrp = get_pid(tty->pgrp);
789 lock_kernel();
790 mutex_unlock(&tty_mutex); 789 mutex_unlock(&tty_mutex);
791 /* XXX: here we race, there is nothing protecting tty */ 790 lock_kernel();
792 if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) 791 if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
793 tty_vhangup(tty); 792 tty_vhangup(tty);
794 unlock_kernel(); 793 unlock_kernel();
794 tty_kref_put(tty);
795 } else if (on_exit) { 795 } else if (on_exit) {
796 struct pid *old_pgrp; 796 struct pid *old_pgrp;
797 spin_lock_irq(&current->sighand->siglock); 797 spin_lock_irq(&current->sighand->siglock);
@@ -819,7 +819,6 @@ void disassociate_ctty(int on_exit)
819 spin_unlock_irq(&current->sighand->siglock); 819 spin_unlock_irq(&current->sighand->siglock);
820 820
821 mutex_lock(&tty_mutex); 821 mutex_lock(&tty_mutex);
822 /* It is possible that do_tty_hangup has free'd this tty */
823 tty = get_current_tty(); 822 tty = get_current_tty();
824 if (tty) { 823 if (tty) {
825 unsigned long flags; 824 unsigned long flags;
@@ -829,6 +828,7 @@ void disassociate_ctty(int on_exit)
829 tty->session = NULL; 828 tty->session = NULL;
830 tty->pgrp = NULL; 829 tty->pgrp = NULL;
831 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 830 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
831 tty_kref_put(tty);
832 } else { 832 } else {
833#ifdef TTY_DEBUG_HANGUP 833#ifdef TTY_DEBUG_HANGUP
834 printk(KERN_DEBUG "error attempted to write to tty [0x%p]" 834 printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
@@ -1806,6 +1806,8 @@ retry_open:
1806 index = tty->index; 1806 index = tty->index;
1807 filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ 1807 filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
1808 /* noctty = 1; */ 1808 /* noctty = 1; */
1809 /* FIXME: Should we take a driver reference ? */
1810 tty_kref_put(tty);
1809 goto got_driver; 1811 goto got_driver;
1810 } 1812 }
1811#ifdef CONFIG_VT 1813#ifdef CONFIG_VT
@@ -3135,7 +3137,7 @@ struct tty_struct *get_current_tty(void)
3135{ 3137{
3136 struct tty_struct *tty; 3138 struct tty_struct *tty;
3137 WARN_ON_ONCE(!mutex_is_locked(&tty_mutex)); 3139 WARN_ON_ONCE(!mutex_is_locked(&tty_mutex));
3138 tty = current->signal->tty; 3140 tty = tty_kref_get(current->signal->tty);
3139 /* 3141 /*
3140 * session->tty can be changed/cleared from under us, make sure we 3142 * session->tty can be changed/cleared from under us, make sure we
3141 * issue the load. The obtained pointer, when not NULL, is valid as 3143 * issue the load. The obtained pointer, when not NULL, is valid as
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index d18e6d2e0b49..3ef5425d0eb8 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -430,11 +430,12 @@ fs3270_open(struct inode *inode, struct file *filp)
430 mutex_lock(&tty_mutex); 430 mutex_lock(&tty_mutex);
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 mutex_unlock(&tty_mutex); 433 tty_kref_put(tty);
434 rc = -ENODEV; 434 rc = -ENODEV;
435 goto out; 435 goto out;
436 } 436 }
437 minor = tty->index + RAW3270_FIRSTMINOR; 437 minor = tty->index + RAW3270_FIRSTMINOR;
438 tty_kref_put(tty);
438 mutex_unlock(&tty_mutex); 439 mutex_unlock(&tty_mutex);
439 } 440 }
440 /* Check if some other program is already using fullscreen mode. */ 441 /* Check if some other program is already using fullscreen mode. */
diff --git a/fs/dquot.c b/fs/dquot.c
index 8ec4d6cc7633..7417a6ca3129 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -897,8 +897,9 @@ static void print_warning(struct dquot *dquot, const int warntype)
897 897
898 mutex_lock(&tty_mutex); 898 mutex_lock(&tty_mutex);
899 tty = get_current_tty(); 899 tty = get_current_tty();
900 mutex_unlock(&tty_mutex);
900 if (!tty) 901 if (!tty)
901 goto out_lock; 902 return;
902 tty_write_message(tty, dquot->dq_sb->s_id); 903 tty_write_message(tty, dquot->dq_sb->s_id);
903 if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN) 904 if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN)
904 tty_write_message(tty, ": warning, "); 905 tty_write_message(tty, ": warning, ");
@@ -926,8 +927,7 @@ static void print_warning(struct dquot *dquot, const int warntype)
926 break; 927 break;
927 } 928 }
928 tty_write_message(tty, msg); 929 tty_write_message(tty, msg);
929out_lock: 930 tty_kref_put(tty);
930 mutex_unlock(&tty_mutex);
931} 931}
932#endif 932#endif
933 933
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 4a7374c12d9c..089d61a23952 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2123,6 +2123,7 @@ static inline void flush_unauthorized_files(struct files_struct *files)
2123 2123
2124 mutex_lock(&tty_mutex); 2124 mutex_lock(&tty_mutex);
2125 tty = get_current_tty(); 2125 tty = get_current_tty();
2126 mutex_unlock(&tty_mutex);
2126 if (tty) { 2127 if (tty) {
2127 file_list_lock(); 2128 file_list_lock();
2128 file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list); 2129 file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list);
@@ -2139,8 +2140,8 @@ static inline void flush_unauthorized_files(struct files_struct *files)
2139 } 2140 }
2140 } 2141 }
2141 file_list_unlock(); 2142 file_list_unlock();
2143 tty_kref_put(tty);
2142 } 2144 }
2143 mutex_unlock(&tty_mutex);
2144 /* Reset controlling tty. */ 2145 /* Reset controlling tty. */
2145 if (drop_tty) 2146 if (drop_tty)
2146 no_tty(); 2147 no_tty();