diff options
author | kib <kib@FreeBSD.org> | 2009-06-08 13:34:45 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2009-06-08 13:34:45 +0000 |
commit | 66aa1d7eeb5ce07985741f334e7e121ee058c568 (patch) | |
tree | 38ac6cba538d03969646dbfd5c2a700f5865384e /sys/kern/tty.c | |
parent | 1568d57c8bb78619488ad83ca0e668ff2d2a6860 (diff) | |
download | FreeBSD-src-66aa1d7eeb5ce07985741f334e7e121ee058c568.zip FreeBSD-src-66aa1d7eeb5ce07985741f334e7e121ee058c568.tar.gz |
Do not dereference vp->v_rdev without holding any of dev_mtx or vnode
lock. Use code similar to devfs_fp_check(), but inlined to feet other
checks performed by ttyhook_register().
Reviewed by: ed
Diffstat (limited to 'sys/kern/tty.c')
-rw-r--r-- | sys/kern/tty.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/sys/kern/tty.c b/sys/kern/tty.c index ba7e6ba..2fa5cf2 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1742,19 +1742,31 @@ ttyhook_register(struct tty **rtp, struct proc *p, int fd, goto done1; } - /* Make sure the vnode is bound to a character device. */ - error = EINVAL; - if (fp->f_type != DTYPE_VNODE || fp->f_vnode->v_type != VCHR || - fp->f_vnode->v_rdev == NULL) + /* + * Make sure the vnode is bound to a character device. + * Unlocked check for the vnode type is ok there, because we + * only shall prevent calling devvn_refthread on the file that + * never has been opened over a character device. + */ + if (fp->f_type != DTYPE_VNODE || fp->f_vnode->v_type != VCHR) { + error = EINVAL; goto done1; - dev = fp->f_vnode->v_rdev; + } /* Make sure it is a TTY. */ - cdp = dev_refthread(dev); - if (cdp == NULL) + cdp = devvn_refthread(fp->f_vnode, &dev); + if (cdp == NULL) { + error = ENXIO; goto done1; - if (cdp != &ttydev_cdevsw) + } + if (dev != fp->f_data) { + error = ENXIO; goto done2; + } + if (cdp != &ttydev_cdevsw) { + error = ENOTTY; + goto done2; + } tp = dev->si_drv1; /* Try to attach the hook to the TTY. */ |