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);