aboutsummaryrefslogtreecommitdiff
path: root/drivers/char
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-10-13 10:39:13 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 09:51:41 -0700
commit452a00d2ee288f2cbc36f676edd06cb14d2878c1 (patch)
treec8251c73924a6ac9b174bc557357bfeff0c8d1a8 /drivers/char
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')
-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 9a76db3cda1..4c0e4ed31a4 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -786,12 +786,12 @@ void disassociate_ctty(int on_exit)
tty = get_current_tty();
if (tty) {
tty_pgrp = get_pid(tty->pgrp);
- lock_kernel();
mutex_unlock(&tty_mutex);
- /* XXX: here we race, there is nothing protecting tty */
+ lock_kernel();
if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
tty_vhangup(tty);
unlock_kernel();
+ tty_kref_put(tty);
} else if (on_exit) {
struct pid *old_pgrp;
spin_lock_irq(&current->sighand->siglock);
@@ -819,7 +819,6 @@ void disassociate_ctty(int on_exit)
spin_unlock_irq(&current->sighand->siglock);
mutex_lock(&tty_mutex);
- /* It is possible that do_tty_hangup has free'd this tty */
tty = get_current_tty();
if (tty) {
unsigned long flags;
@@ -829,6 +828,7 @@ void disassociate_ctty(int on_exit)
tty->session = NULL;
tty->pgrp = NULL;
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+ tty_kref_put(tty);
} else {
#ifdef TTY_DEBUG_HANGUP
printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
@@ -1806,6 +1806,8 @@ retry_open:
index = tty->index;
filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
/* noctty = 1; */
+ /* FIXME: Should we take a driver reference ? */
+ tty_kref_put(tty);
goto got_driver;
}
#ifdef CONFIG_VT
@@ -3135,7 +3137,7 @@ struct tty_struct *get_current_tty(void)
{
struct tty_struct *tty;
WARN_ON_ONCE(!mutex_is_locked(&tty_mutex));
- tty = current->signal->tty;
+ 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