aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
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 /drivers/char/tty_io.c
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>
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c10
1 files changed, 6 insertions, 4 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