diff options
author | Alan Cox <alan@redhat.com> | 2008-10-13 10:39:13 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-13 09:51:41 -0700 |
commit | 452a00d2ee288f2cbc36f676edd06cb14d2878c1 (patch) | |
tree | c8251c73924a6ac9b174bc557357bfeff0c8d1a8 /drivers/char/tty_io.c | |
parent | f4d2a6c2096b764decb20070b1bf4356de9144a8 (diff) | |
download | lwn-452a00d2ee288f2cbc36f676edd06cb14d2878c1.tar.gz lwn-452a00d2ee288f2cbc36f676edd06cb14d2878c1.zip |
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.c | 10 |
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) 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(¤t->sighand->siglock); @@ -819,7 +819,6 @@ void disassociate_ctty(int on_exit) spin_unlock_irq(¤t->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 |