summaryrefslogtreecommitdiffstats
path: root/sys/kern/tty_tty.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2007-07-03 17:46:37 +0000
committerkib <kib@FreeBSD.org>2007-07-03 17:46:37 +0000
commit764028016fb7c8690eca612fc2105107e23ed996 (patch)
tree55a187ec386c3dc03049b96e7265897c950251c9 /sys/kern/tty_tty.c
parenta1bd6e4f521b174d396ccbdef6bd171a2e37d5ae (diff)
downloadFreeBSD-src-764028016fb7c8690eca612fc2105107e23ed996.zip
FreeBSD-src-764028016fb7c8690eca612fc2105107e23ed996.tar.gz
Lock Giant and proctree lock around dereferencing p_session->s_ttyvp->v_rdev.
Lock cdev mutex too to close the race with tty being freed. Relock clone_drain_lock to prevent the LOR with proctree lock, thus add #include <fs/devfs/devfs_int.h>. Suggested by: tegge Debugging help and testing by: Peter Holm Approved by: re (kensmith)
Diffstat (limited to 'sys/kern/tty_tty.c')
-rw-r--r--sys/kern/tty_tty.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/sys/kern/tty_tty.c b/sys/kern/tty_tty.c
index 8a04185..0b10f83 100644
--- a/sys/kern/tty_tty.c
+++ b/sys/kern/tty_tty.c
@@ -31,8 +31,12 @@ __FBSDID("$FreeBSD$");
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/proc.h>
+#include <sys/sx.h>
#include <sys/vnode.h>
+#include <fs/devfs/devfs.h>
+#include <fs/devfs/devfs_int.h>
+
static d_open_t cttyopen;
static struct cdevsw ctty_cdevsw = {
@@ -60,6 +64,11 @@ ctty_clone(void *arg, struct ucred *cred, char *name, int namelen,
return;
if (strcmp(name, "tty"))
return;
+ sx_sunlock(&clone_drain_lock);
+ mtx_lock(&Giant);
+ sx_slock(&proctree_lock);
+ sx_slock(&clone_drain_lock);
+ dev_lock();
if (!(curthread->td_proc->p_flag & P_CONTROLT))
*dev = ctty;
else if (curthread->td_proc->p_session->s_ttyvp == NULL)
@@ -70,7 +79,10 @@ ctty_clone(void *arg, struct ucred *cred, char *name, int namelen,
*dev = ctty;
} else
*dev = curthread->td_proc->p_session->s_ttyvp->v_rdev;
- dev_ref(*dev);
+ dev_refl(*dev);
+ dev_unlock();
+ sx_sunlock(&proctree_lock);
+ mtx_unlock(&Giant);
}
static void
OpenPOWER on IntegriCloud