DF-0176 / fix.diff
diff --git a/sys/kern/tty_tty.c b/sys/kern/tty_tty.c --- a/sys/kern/tty_tty.c +++ b/sys/kern/tty_tty.c @@ -233,6 +233,7 @@ { struct vnode *ttyvp; struct proc *p = curproc; + int error; KKASSERT(p); lwkt_gettoken(&p->p_token); @@ -261,8 +262,19 @@ } lwkt_reltoken(&p->p_token); - return (VOP_IOCTL(ttyvp, ap->a_cmd, ap->a_data, ap->a_fflag, - ap->a_cred, ap->a_sysmsg)); + /* + * Take a vnode reference so ttyvp cannot be vrele'd/reclaimed + * while VOP_IOCTL runs. Matches what cttyread/cttywrite do via + * vget(); cttyioctl previously dereferenced ttyvp unlocked. + * (DF-0176) + */ + error = vget(ttyvp, LK_EXCLUSIVE | LK_RETRY); + if (error) + return (EIO); + error = VOP_IOCTL(ttyvp, ap->a_cmd, ap->a_data, ap->a_fflag, + ap->a_cred, ap->a_sysmsg); + vput(ttyvp); + return (error); } static struct filterops cttyfiltops_read = |