diff --git a/sys/dev/snp/snp.c b/sys/dev/snp/snp.c index f2dcc1b75f99..8d6485c72d48 100644 --- a/sys/dev/snp/snp.c +++ b/sys/dev/snp/snp.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -246,7 +247,7 @@ snp_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, sx_xunlock(&snp_register_lock); return (EBUSY); } - error = ttyhook_register(&ss->snp_tty, td, *(int *)data, + error = ttyhook_register(&ss->snp_tty, td->td_proc, *(int *)data, &snp_hook, ss); sx_xunlock(&snp_register_lock); if (error != 0) diff --git a/sys/kern/tty.c b/sys/kern/tty.c index e0045cea582d..30c2633d95ce 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #ifdef COMPAT_43TTY #include @@ -1673,18 +1674,24 @@ ttyhook_defrint(struct tty *tp, char c, int flags) } int -ttyhook_register(struct tty **rtp, struct thread *td, int fd, +ttyhook_register(struct tty **rtp, struct proc *p, int fd, struct ttyhook *th, void *softc) { struct tty *tp; struct file *fp; struct cdev *dev; struct cdevsw *cdp; + struct filedesc *fdp; int error; /* Validate the file descriptor. */ - if (fget(td, fd, &fp) != 0) - return (EINVAL); + if ((fdp = p->p_fd) == NULL) + return (EBADF); + FILEDESC_SLOCK(fdp); + if ((fp = fget_locked(fdp, fd)) == NULL || fp->f_ops == &badfileops) { + FILEDESC_SUNLOCK(fdp); + return (EBADF); + } /* Make sure the vnode is bound to a character device. */ error = EINVAL; @@ -1723,7 +1730,7 @@ ttyhook_register(struct tty **rtp, struct thread *td, int fd, done3: tty_unlock(tp); done2: dev_relthread(dev); -done1: fdrop(fp, td); +done1: FILEDESC_SUNLOCK(fdp); return (error); } diff --git a/sys/netgraph/ng_tty.c b/sys/netgraph/ng_tty.c index c504b8479f9e..0e69e77349ba 100644 --- a/sys/netgraph/ng_tty.c +++ b/sys/netgraph/ng_tty.c @@ -252,7 +252,6 @@ static int ngt_rcvmsg(node_p node, item_p item, hook_p lasthook) { struct proc *p; - struct thread *td; const sc_p sc = NG_NODE_PRIVATE(node); struct ng_mesg *msg, *resp = NULL; int error = 0; @@ -266,12 +265,13 @@ ngt_rcvmsg(node_p node, item_p item, hook_p lasthook) return (EBUSY); p = pfind(((int *)msg->data)[0]); - if (p == NULL) + if (p == NULL || (p->p_flag & P_WEXIT)) return (ESRCH); - td = FIRST_THREAD_IN_PROC(p); - error = ttyhook_register(&sc->tp, td, ((int *)msg->data)[1], - &ngt_hook, sc); + _PHOLD(p); PROC_UNLOCK(p); + error = ttyhook_register(&sc->tp, p, ((int *)msg->data)[1], + &ngt_hook, sc); + PRELE(p); if (error != 0) return (error); break; diff --git a/sys/sys/ttyhook.h b/sys/sys/ttyhook.h index 7a0a0bc13f52..2a6d0887acb8 100644 --- a/sys/sys/ttyhook.h +++ b/sys/sys/ttyhook.h @@ -66,7 +66,7 @@ struct ttyhook { th_close_t *th_close; }; -int ttyhook_register(struct tty **, struct thread *, int, +int ttyhook_register(struct tty **, struct proc *, int, struct ttyhook *, void *); void ttyhook_unregister(struct tty *); #define ttyhook_softc(tp) ((tp)->t_hooksoftc)