Subject: Re: coredump following symlinks
To: Manuel Bouyer <bouyer@antioche.lip6.fr>
From: Bill Sommerfeld <sommerfeld@orchard.arlington.ma.us>
List: tech-kern
Date: 08/27/1999 10:47:36
> Index: kern_sig.c
> ===================================================================
> RCS file: /cvsroot/syssrc/sys/kern/kern_sig.c,v
> retrieving revision 1.92
> diff -u -r1.92 kern_sig.c
> --- kern_sig.c	1999/07/25 06:30:34	1.92
> +++ kern_sig.c	1999/08/27 14:18:59
> @@ -1263,6 +1263,7 @@
>  	register struct ucred *cred = p->p_cred->pc_ucred;
>  	struct nameidata nd;
>  	struct vattr vattr;
> +	struct stat stat;
>  	int error, error1;
>  	char name[MAXCOMLEN+6];		/* progname.core */
>  	struct core core;
> @@ -1297,6 +1298,22 @@
>  		sprintf(name, "core");
>  	else
>  		sprintf(name, "%s.core", p->p_comm);
> +	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_SYSSPACE, name, p);
> +	error = namei(&nd);
> +	if (error == 0) {
> +		error = vn_stat(nd.ni_vp, &stat, p);
> +		vput(nd.ni_vp);
> +		if (error)
> +			return error;
> +		/*
> +		 * Don't dump if the owner of the
> +		 * process is not the one owning the existing file/symlink
> +		 */
> +		if (stat.st_uid != p->p_ucred->cr_uid)
> +			return EINVAL;
> +	} else if (error != ENOENT)
> +		return error;
> +	/* Now follow symlink if there is one */
>  	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, name, p);
>  	error = vn_open(&nd, O_CREAT | FWRITE, S_IRUSR | S_IWUSR);
>  	if (error)
> 
> --0OAP2g/MAC+5xKAE--
	
This still has a potential race between the first and the second call
to namei().  Yes, this is much harder to exploit, but there's still a
window during which an attacker could sneak a symlink in there
sideways..

					- Bill