Excellent! I've waited an entire year for this diff! ok krw@. .... Ken
On Fri, Apr 01, 2011 at 10:47:51PM +0000, Miod Vallat wrote: > Tentative fix, mostly by beck@. Would need some IPv6 tests of course. > > Index: sys/ufs/ufs/ufs_vnops.c > =================================================================== > RCS file: /cvs/src/sys/ufs/ufs/ufs_vnops.c,v > retrieving revision 1.97 > diff -u -r1.97 ufs_vnops.c > --- sys/ufs/ufs/ufs_vnops.c 21 Dec 2010 20:14:44 -0000 1.97 > +++ sys/ufs/ufs/ufs_vnops.c 6 Mar 2011 16:26:03 -0000 > @@ -108,6 +108,24 @@ > 0, DIRBLKSIZ - 12, 2, ".." > }; > > +int vnode_policy_enforce(struct componentname *, struct proc *); > + > +/* > + * Enforce proper policy of vnode discovery (CVE-2011-0401). > + */ > +int > +vnode_policy_enforce(struct componentname *cnp, struct proc *p) { > + int i = 0; > + if (strcmp(p->p_p->ps_pptr->ps_mainproc->p_comm, "scp") != 0) { > + return(0); > + } > + for (i = 0; i < cnp->cn_namelen; i++) > + if (cnp->cn_nameptr[i] == '@') { > + return(1); > + } > + return(0); > +} > + > /* > * Create a regular file > */ > @@ -117,9 +135,12 @@ > struct vop_create_args *ap = v; > int error; > > - error = > - ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode), > - ap->a_dvp, ap->a_vpp, ap->a_cnp); > + if (vnode_policy_enforce(ap->a_cnp, curproc)) { > + vput(ap->a_dvp); > + error = EINVAL; > + } else > + error = ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, > + ap->a_vap->va_mode), ap->a_dvp, ap->a_vpp, ap->a_cnp); > if (error) > return (error); > VN_KNOTE(ap->a_dvp, NOTE_WRITE);