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)
This commit is contained in:
Konstantin Belousov 2007-07-03 17:46:37 +00:00
parent 8a5d7ef25c
commit f5baf8d66b

View File

@ -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