Module Name:    src
Committed By:   dholland
Date:           Sun May  2 05:30:20 UTC 2010

Modified Files:
        src/sys/compat/osf1: osf1_exec_ecoff.c
        src/sys/compat/svr4_32: svr4_32_exec_elf32.c
        src/sys/kern: exec_script.c kern_exec.c
        src/sys/sys: exec.h

Log Message:
Remove the nameidata from struct exec_package. It was used only for two
things: passing an argument to check_exec, which is better done explicitly,
and handing back the resolved pathname generated by namei, which we can
make an explicit slot for in struct exec_package instead. While here,
perform some related tidyup, and store the kernel-side copy of the path
to the executable as well as the pointer into userspace. (But the latter
should probably be removed in the future.)


To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/sys/compat/osf1/osf1_exec_ecoff.c
cvs rdiff -u -r1.20 -r1.21 src/sys/compat/svr4_32/svr4_32_exec_elf32.c
cvs rdiff -u -r1.63 -r1.64 src/sys/kern/exec_script.c
cvs rdiff -u -r1.294 -r1.295 src/sys/kern/kern_exec.c
cvs rdiff -u -r1.129 -r1.130 src/sys/sys/exec.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/compat/osf1/osf1_exec_ecoff.c
diff -u src/sys/compat/osf1/osf1_exec_ecoff.c:1.21 src/sys/compat/osf1/osf1_exec_ecoff.c:1.22
--- src/sys/compat/osf1/osf1_exec_ecoff.c:1.21	Sat Nov 15 00:49:53 2008
+++ src/sys/compat/osf1/osf1_exec_ecoff.c	Sun May  2 05:30:20 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: osf1_exec_ecoff.c,v 1.21 2008/11/15 00:49:53 njoly Exp $ */
+/* $NetBSD: osf1_exec_ecoff.c,v 1.22 2010/05/02 05:30:20 dholland Exp $ */
 
 /*
  * Copyright (c) 1999 Christopher G. Demetriou.  All rights reserved.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: osf1_exec_ecoff.c,v 1.21 2008/11/15 00:49:53 njoly Exp $");
+__KERNEL_RCSID(0, "$NetBSD: osf1_exec_ecoff.c,v 1.22 2010/05/02 05:30:20 dholland Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -73,16 +73,8 @@
 	epp->ep_emul_arg = emul_arg;
 
 	emul_arg->flags = 0;
-	if (epp->ep_ndp->ni_segflg == UIO_SYSSPACE)
-		error = copystr(epp->ep_ndp->ni_dirp, emul_arg->exec_name,
-		    MAXPATHLEN + 1, NULL);
-	else
-		error = copyinstr(epp->ep_ndp->ni_dirp, emul_arg->exec_name,
-		    MAXPATHLEN + 1, NULL);
-#ifdef DIAGNOSTIC
-	if (error != 0)
-		panic("osf1_exec_ecoff_probe: copyinstr failed");
-#endif
+	/* this cannot overflow because both are size PATH_MAX */
+	strcpy(emul_arg->exec_name, epp->ep_kname);
 
 	/* do any special object file handling */
 	switch (execp->f.f_flags & ECOFF_FLAG_OBJECT_TYPE_MASK) {

Index: src/sys/compat/svr4_32/svr4_32_exec_elf32.c
diff -u src/sys/compat/svr4_32/svr4_32_exec_elf32.c:1.20 src/sys/compat/svr4_32/svr4_32_exec_elf32.c:1.21
--- src/sys/compat/svr4_32/svr4_32_exec_elf32.c:1.20	Mon Apr 28 20:23:46 2008
+++ src/sys/compat/svr4_32/svr4_32_exec_elf32.c	Sun May  2 05:30:20 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: svr4_32_exec_elf32.c,v 1.20 2008/04/28 20:23:46 martin Exp $	 */
+/*	$NetBSD: svr4_32_exec_elf32.c,v 1.21 2010/05/02 05:30:20 dholland Exp $	 */
 
 /*-
  * Copyright (c) 1994 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: svr4_32_exec_elf32.c,v 1.20 2008/04/28 20:23:46 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: svr4_32_exec_elf32.c,v 1.21 2010/05/02 05:30:20 dholland Exp $");
 
 #define	ELFSIZE		32				/* XXX should die */
 
@@ -93,11 +93,9 @@
 		platform = a; /* Patch this later. */
 		a++;
 
-		if (pack->ep_ndp->ni_cnd.cn_flags & HASBUF) {
-			a->a_type = AT_SUN_EXECNAME;
-			exec = a; /* Patch this later. */
-			a++;
-		}
+		a->a_type = AT_SUN_EXECNAME;
+		exec = a; /* Patch this later. */
+		a++;
 
 		a->a_type = AT_PHDR;
 		a->a_v = ap->arg_phaddr;
@@ -173,7 +171,7 @@
 		len += strlen(machine_model) + 1;
 
 		if (exec) {
-			path = pack->ep_ndp->ni_cnd.cn_pnbuf;
+			path = pack->ep_resolvedname;
 
 			/* Copy out the file we're executing. */
 			exec->a_v = (u_long)(*stackp) + len;

Index: src/sys/kern/exec_script.c
diff -u src/sys/kern/exec_script.c:1.63 src/sys/kern/exec_script.c:1.64
--- src/sys/kern/exec_script.c:1.63	Wed Nov 19 18:36:06 2008
+++ src/sys/kern/exec_script.c	Sun May  2 05:30:20 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: exec_script.c,v 1.63 2008/11/19 18:36:06 ad Exp $	*/
+/*	$NetBSD: exec_script.c,v 1.64 2010/05/02 05:30:20 dholland Exp $	*/
 
 /*
  * Copyright (c) 1993, 1994, 1996 Christopher G. Demetriou
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: exec_script.c,v 1.63 2008/11/19 18:36:06 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: exec_script.c,v 1.64 2010/05/02 05:30:20 dholland Exp $");
 
 #if defined(SETUIDSCRIPTS) && !defined(FDSCRIPTS)
 #define FDSCRIPTS		/* Need this for safe set-id scripts. */
@@ -115,7 +115,7 @@
 {
 	int error, hdrlinelen, shellnamelen, shellarglen;
 	char *hdrstr = epp->ep_hdr;
-	char *cp, *shellname, *shellarg, *oldpnbuf;
+	char *cp, *shellname, *shellarg;
 	size_t shellargp_len;
 	struct exec_fakearg *shellargp;
 	struct exec_fakearg *tmpsap;
@@ -247,12 +247,7 @@
 	}
 #endif
 
-	/* set up the parameters for the recursive check_exec() call */
-	epp->ep_ndp->ni_dirp = shellname;
-	epp->ep_ndp->ni_segflg = UIO_SYSSPACE;
-	epp->ep_flags |= EXEC_INDIR;
-
-	/* and set up the fake args list, for later */
+	/* set up the fake args list */
 	shellargp_len = 4 * sizeof(*shellargp);
 	shellargp = kmem_alloc(shellargp_len, KM_SLEEP);
 	tmpsap = shellargp;
@@ -272,12 +267,12 @@
 	if ((epp->ep_flags & EXEC_HASFD) == 0) {
 #endif
 		/* normally can't fail, but check for it if diagnostic */
-		error = copyinstr(epp->ep_name, tmpsap->fa_arg, MAXPATHLEN,
+		error = copystr(epp->ep_kname, tmpsap->fa_arg, MAXPATHLEN,
 		    (size_t *)0);
 		tmpsap++;
 #ifdef DIAGNOSTIC
 		if (error != 0)
-			panic("exec_script: copyinstr couldn't fail");
+			panic("exec_script: copystr couldn't fail");
 #endif
 #ifdef FDSCRIPTS
 	} else {
@@ -287,22 +282,25 @@
 #endif
 	tmpsap->fa_arg = NULL;
 
+	/* Save the old vnode so we can clean it up later. */
+	scriptvp = epp->ep_vp;
+	epp->ep_vp = NULL;
+
+	/* Note that we're trying recursively. */
+	epp->ep_flags |= EXEC_INDIR;
+
 	/*
 	 * mark the header we have as invalid; check_exec will read
 	 * the header from the new executable
 	 */
 	epp->ep_hdrvalid = 0;
 
-	/*
-	 * remember the old vp and pnbuf for later, so we can restore
-	 * them if check_exec() fails.
-	 */
-	scriptvp = epp->ep_vp;
-	oldpnbuf = epp->ep_ndp->ni_cnd.cn_pnbuf;
+	/* try loading the interpreter */
+	error = check_exec(l, epp, shellname);
 
-	error = check_exec(l, epp);
 	/* note that we've clobbered the header */
 	epp->ep_flags |= EXEC_DESTR;
+
 	if (error == 0) {
 		/*
 		 * It succeeded.  Unlock the script and
@@ -316,9 +314,6 @@
 			vput(scriptvp);
 		}
 
-		/* free the old pathname buffer */
-		PNBUF_PUT(oldpnbuf);
-
 		epp->ep_flags |= (EXEC_HASARGL | EXEC_SKIPARG);
 		epp->ep_fa = shellargp;
 		epp->ep_fa_len = shellargp_len;
@@ -338,8 +333,6 @@
 		return (0);
 	}
 
-	/* XXX oldpnbuf not set for "goto fail" path */
-	epp->ep_ndp->ni_cnd.cn_pnbuf = oldpnbuf;
 #ifdef FDSCRIPTS
 fail:
 #endif
@@ -354,8 +347,6 @@
 		vput(scriptvp);
 	}
 
-        PNBUF_PUT(epp->ep_ndp->ni_cnd.cn_pnbuf);
-
 	/* free the fake arg list, because we're not returning it */
 	if ((tmpsap = shellargp) != NULL) {
 		while (tmpsap->fa_arg != NULL) {

Index: src/sys/kern/kern_exec.c
diff -u src/sys/kern/kern_exec.c:1.294 src/sys/kern/kern_exec.c:1.295
--- src/sys/kern/kern_exec.c:1.294	Mon Mar  1 21:10:15 2010
+++ src/sys/kern/kern_exec.c	Sun May  2 05:30:20 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_exec.c,v 1.294 2010/03/01 21:10:15 darran Exp $	*/
+/*	$NetBSD: kern_exec.c,v 1.295 2010/05/02 05:30:20 dholland Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.294 2010/03/01 21:10:15 darran Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.295 2010/05/02 05:30:20 dholland Exp $");
 
 #include "opt_ktrace.h"
 #include "opt_modular.h"
@@ -278,20 +278,29 @@
  */
 int
 /*ARGSUSED*/
-check_exec(struct lwp *l, struct exec_package *epp)
+check_exec(struct lwp *l, struct exec_package *epp, const char *kpath)
 {
 	int		error, i;
 	struct vnode	*vp;
-	struct nameidata *ndp;
+	struct nameidata nd;
 	size_t		resid;
 
-	ndp = epp->ep_ndp;
-	ndp->ni_cnd.cn_nameiop = LOOKUP;
-	ndp->ni_cnd.cn_flags = FOLLOW | LOCKLEAF | SAVENAME | TRYEMULROOT;
+	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | SAVENAME | TRYEMULROOT,
+	       UIO_SYSSPACE, kpath);
+
 	/* first get the vnode */
-	if ((error = namei(ndp)) != 0)
+	if ((error = namei(&nd)) != 0)
 		return error;
-	epp->ep_vp = vp = ndp->ni_vp;
+	epp->ep_vp = vp = nd.ni_vp;
+	/* this cannot overflow as both are size PATH_MAX */
+	strcpy(epp->ep_resolvedname, nd.ni_cnd.cn_pnbuf);
+
+	/* dump this right away */
+#if 1 /*def DIAGNOSTIC*/
+	/* paranoia (XXX: take this out once things are working) */
+	memset(nd.ni_cnd.cn_pnbuf, '~', PATH_MAX);
+#endif
+	PNBUF_PUT(nd.ni_cnd.cn_pnbuf);
 
 	/* check access and type */
 	if (vp->v_type != VREG) {
@@ -321,7 +330,7 @@
 	VOP_UNLOCK(vp, 0);
 
 #if NVERIEXEC > 0
-	error = veriexec_verify(l, vp, ndp->ni_cnd.cn_pnbuf,
+	error = veriexec_verify(l, vp, epp->ep_resolvedname,
 	    epp->ep_flags & EXEC_INDIR ? VERIEXEC_INDIRECT : VERIEXEC_DIRECT,
 	    NULL);
 	if (error)
@@ -329,7 +338,7 @@
 #endif /* NVERIEXEC > 0 */
 
 #ifdef PAX_SEGVGUARD
-	error = pax_segvguard(l, vp, ndp->ni_cnd.cn_pnbuf, false);
+	error = pax_segvguard(l, vp, epp->ep_resolvedname, false);
 	if (error)
 		goto bad2;
 #endif /* PAX_SEGVGUARD */
@@ -411,7 +420,6 @@
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 	VOP_CLOSE(vp, FREAD, l->l_cred);
 	vput(vp);
-	PNBUF_PUT(ndp->ni_cnd.cn_pnbuf);
 	return error;
 
 bad1:
@@ -420,7 +428,6 @@
 	 * (which we don't yet have open).
 	 */
 	vput(vp);				/* was still locked */
-	PNBUF_PUT(ndp->ni_cnd.cn_pnbuf);
 	return error;
 }
 
@@ -513,7 +520,6 @@
 {
 	int			error;
 	struct exec_package	pack;
-	struct nameidata	nid;
 	struct vattr		attr;
 	struct proc		*p;
 	char			*argp;
@@ -531,7 +537,8 @@
 	ksiginfo_t		ksi;
 	ksiginfoq_t		kq;
 	char			*pathbuf;
-	size_t			pathbuflen;
+	char			*resolvedpathbuf;
+	const char		*commandname;
 	u_int			modgen;
 
 	p = l->l_proc;
@@ -584,22 +591,25 @@
 	 * see exec_script_makecmds().
 	 */
 	pathbuf = PNBUF_GET();
-	error = copyinstr(path, pathbuf, MAXPATHLEN, &pathbuflen);
+	error = copyinstr(path, pathbuf, MAXPATHLEN, NULL);
 	if (error) {
 		DPRINTF(("execve: copyinstr path %d", error));
 		goto clrflg;
 	}
-
-	NDINIT(&nid, LOOKUP, NOFOLLOW | TRYEMULROOT, UIO_SYSSPACE, pathbuf);
+	resolvedpathbuf = PNBUF_GET();
+#ifdef DIAGNOSTIC
+	strcpy(resolvedpathbuf, "/wrong");
+#endif
 
 	/*
 	 * initialize the fields of the exec package.
 	 */
 	pack.ep_name = path;
+	pack.ep_kname = pathbuf;
+	pack.ep_resolvedname = resolvedpathbuf;
 	pack.ep_hdr = kmem_alloc(exec_maxhdrsz, KM_SLEEP);
 	pack.ep_hdrlen = exec_maxhdrsz;
 	pack.ep_hdrvalid = 0;
-	pack.ep_ndp = &nid;
 	pack.ep_emul_arg = NULL;
 	pack.ep_vmcmds.evs_cnt = 0;
 	pack.ep_vmcmds.evs_used = 0;
@@ -613,7 +623,7 @@
 	rw_enter(&exec_lock, RW_READER);
 
 	/* see if we can run it. */
-	if ((error = check_exec(l, &pack)) != 0) {
+	if ((error = check_exec(l, &pack, pathbuf)) != 0) {
 		if (error != ENOENT) {
 			DPRINTF(("execve: check exec failed %d\n", error));
 		}
@@ -853,8 +863,14 @@
 	arginfo.ps_nenvstr = envc;
 
 	/* set command name & other accounting info */
-	i = min(nid.ni_cnd.cn_namelen, MAXCOMLEN);
-	(void)memcpy(p->p_comm, nid.ni_cnd.cn_nameptr, i);
+	commandname = strrchr(pack.ep_resolvedname, '/');
+	if (commandname != NULL) {
+		commandname++;
+	} else {
+		commandname = pack.ep_resolvedname;
+	}
+	i = min(strlen(commandname), MAXCOMLEN);
+	(void)memcpy(p->p_comm, commandname, i);
 	p->p_comm[i] = '\0';
 
 	dp = PNBUF_GET();
@@ -1075,8 +1091,6 @@
 
 	pool_put(&exec_pool, argp);
 
-	PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
-
 	/* notify others that we exec'd */
 	KNOTE(&p->p_klist, NOTE_EXEC);
 
@@ -1163,6 +1177,7 @@
 	}
 
 	PNBUF_PUT(pathbuf);
+	PNBUF_PUT(resolvedpathbuf);
 	return (EJUSTRETURN);
 
  bad:
@@ -1177,7 +1192,6 @@
 	vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY);
 	VOP_CLOSE(pack.ep_vp, FREAD, l->l_cred);
 	vput(pack.ep_vp);
-	PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
 	pool_put(&exec_pool, argp);
 
  freehdr:
@@ -1189,6 +1203,8 @@
 
 	rw_exit(&exec_lock);
 
+	PNBUF_PUT(resolvedpathbuf);
+
  clrflg:
 	lwp_lock(l);
 	l->l_flag |= oldlwpflags;
@@ -1208,6 +1224,7 @@
  exec_abort:
 	SDT_PROBE(proc,,,exec_failure, error, 0, 0, 0, 0);
 	PNBUF_PUT(pathbuf);
+	PNBUF_PUT(resolvedpathbuf);
 	rw_exit(&p->p_reflock);
 	rw_exit(&exec_lock);
 
@@ -1220,7 +1237,6 @@
 		VM_MAXUSER_ADDRESS - VM_MIN_ADDRESS);
 	if (pack.ep_emul_arg)
 		free(pack.ep_emul_arg, M_TEMP);
-	PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
 	pool_put(&exec_pool, argp);
 	kmem_free(pack.ep_hdr, pack.ep_hdrlen);
 	if (pack.ep_emul_root != NULL)

Index: src/sys/sys/exec.h
diff -u src/sys/sys/exec.h:1.129 src/sys/sys/exec.h:1.130
--- src/sys/sys/exec.h:1.129	Mon Dec 14 00:48:35 2009
+++ src/sys/sys/exec.h	Sun May  2 05:30:20 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: exec.h,v 1.129 2009/12/14 00:48:35 matt Exp $	*/
+/*	$NetBSD: exec.h,v 1.130 2010/05/02 05:30:20 dholland Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -171,10 +171,11 @@
 
 struct exec_package {
 	const char *ep_name;		/* file's name */
+	const char *ep_kname;		/* kernel-side copy of file's name */
+	char *ep_resolvedname;		/* fully resolved path from namei */
 	void	*ep_hdr;		/* file's exec header */
 	u_int	ep_hdrlen;		/* length of ep_hdr */
 	u_int	ep_hdrvalid;		/* bytes of ep_hdr that are valid */
-	struct nameidata *ep_ndp;	/* namei data pointer for lookups */
 	struct	exec_vmcmd_set ep_vmcmds;  /* vmcmds used to build vmspace */
 	struct	vnode *ep_vp;		/* executable's vnode */
 	struct	vattr *ep_vap;		/* executable's attributes */
@@ -243,7 +244,8 @@
 void	setregs			(struct lwp *, struct exec_package *, vaddr_t);
 int	check_veriexec		(struct lwp *, struct vnode *,
 				     struct exec_package *, int);
-int	check_exec		(struct lwp *, struct exec_package *);
+int	check_exec		(struct lwp *, struct exec_package *,
+				     const char *kpath);
 int	exec_init		(int);
 int	exec_read_from		(struct lwp *, struct vnode *, u_long off,
 				    void *, size_t);

Reply via email to