Module Name: src Committed By: christos Date: Tue Nov 7 19:44:05 UTC 2017
Modified Files: src/sys/kern: exec_elf.c kern_exec.c kern_exit.c kern_fork.c kern_proc.c src/sys/sys: exec.h param.h proc.h Log Message: Store full executable path in p->p_path as discussed in tech-kern. This means that the full executable path is always available. - exec_elf.c: use p->path to set AT_SUN_EXECNAME, and since this is always set, do so unconditionally. - kern_exec.c: simplify pathexec, use kmem_strfree where appropriate and set p->p_path - kern_exit.c: free p->p_path - kern_fork.c: set p->p_path for the child. - kern_proc.c: use p->p_path to return the executable pathname; the NULL check for p->p_path, should be a KASSERT? - exec.h: gc ep_path, it is not used anymore - param.h: bump version, 'struct proc' size change TODO: 1. reference count the path string, to save copy at fork and free just before exec? 2. canonicalize the pathname by changing namei() to LOCKPARENT vnode and then using getcwd() on the parent directory? To generate a diff of this commit: cvs rdiff -u -r1.92 -r1.93 src/sys/kern/exec_elf.c cvs rdiff -u -r1.449 -r1.450 src/sys/kern/kern_exec.c cvs rdiff -u -r1.269 -r1.270 src/sys/kern/kern_exit.c cvs rdiff -u -r1.202 -r1.203 src/sys/kern/kern_fork.c cvs rdiff -u -r1.207 -r1.208 src/sys/kern/kern_proc.c cvs rdiff -u -r1.151 -r1.152 src/sys/sys/exec.h cvs rdiff -u -r1.549 -r1.550 src/sys/sys/param.h cvs rdiff -u -r1.342 -r1.343 src/sys/sys/proc.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/kern/exec_elf.c diff -u src/sys/kern/exec_elf.c:1.92 src/sys/kern/exec_elf.c:1.93 --- src/sys/kern/exec_elf.c:1.92 Sun Oct 15 21:50:55 2017 +++ src/sys/kern/exec_elf.c Tue Nov 7 14:44:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: exec_elf.c,v 1.92 2017/10/16 01:50:55 christos Exp $ */ +/* $NetBSD: exec_elf.c,v 1.93 2017/11/07 19:44:04 christos Exp $ */ /*- * Copyright (c) 1994, 2000, 2005, 2015 The NetBSD Foundation, Inc. @@ -57,7 +57,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.92 2017/10/16 01:50:55 christos Exp $"); +__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.93 2017/11/07 19:44:04 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_pax.h" @@ -226,11 +226,9 @@ elf_copyargs(struct lwp *l, struct exec_ a->a_v = l->l_proc->p_stackbase; a++; - if (pack->ep_path) { - execname = a; - a->a_type = AT_SUN_EXECNAME; - a++; - } + execname = a; + a->a_type = AT_SUN_EXECNAME; + a++; exec_free_emul_arg(pack); } @@ -243,15 +241,12 @@ elf_copyargs(struct lwp *l, struct exec_ KASSERT(vlen <= sizeof(ai)); - if (execname) { - char *path = pack->ep_path; - execname->a_v = (uintptr_t)(*stackp + vlen); - len = strlen(path) + 1; - if ((error = copyout(path, (*stackp + vlen), len)) != 0) - return error; - len = ALIGN(len); - } else - len = 0; + char *path = l->l_proc->p_path; + execname->a_v = (uintptr_t)(*stackp + vlen); + len = strlen(path) + 1; + if ((error = copyout(path, (*stackp + vlen), len)) != 0) + return error; + len = ALIGN(len); if ((error = copyout(ai, *stackp, vlen)) != 0) return error; Index: src/sys/kern/kern_exec.c diff -u src/sys/kern/kern_exec.c:1.449 src/sys/kern/kern_exec.c:1.450 --- src/sys/kern/kern_exec.c:1.449 Fri Oct 20 15:06:46 2017 +++ src/sys/kern/kern_exec.c Tue Nov 7 14:44:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exec.c,v 1.449 2017/10/20 19:06:46 riastradh Exp $ */ +/* $NetBSD: kern_exec.c,v 1.450 2017/11/07 19:44:04 christos 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.449 2017/10/20 19:06:46 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.450 2017/11/07 19:44:04 christos Exp $"); #include "opt_exec.h" #include "opt_execfmt.h" @@ -925,55 +925,15 @@ execve_free_data(struct execve_data *dat } static void -pathexec(struct exec_package *epp, struct lwp *l, const char *pathstring) +pathexec(struct proc *p, const char *resolvedname) { - const char *commandname; - size_t commandlen; - char *path; - struct proc *p = l->l_proc; + KASSERT(resolvedname[0] == '/'); /* set command name & other accounting info */ - commandname = strrchr(epp->ep_resolvedname, '/'); - if (commandname != NULL) { - commandname++; - } else { - commandname = epp->ep_resolvedname; - } - commandlen = min(strlen(commandname), MAXCOMLEN); - (void)memcpy(p->p_comm, commandname, commandlen); - p->p_comm[commandlen] = '\0'; - + strlcpy(p->p_comm, strrchr(resolvedname, '/') + 1, sizeof(p->p_comm)); - /* - * If the path starts with /, we don't need to do any work. - * This handles the majority of the cases. - * In the future perhaps we could canonicalize it? - */ - path = PNBUF_GET(); - if (pathstring[0] == '/') { - (void)strlcpy(path, pathstring, MAXPATHLEN); - epp->ep_path = path; - } -#ifdef notyet - /* - * Although this works most of the time [since the entry was just - * entered in the cache] we don't use it because it will fail for - * entries that are not placed in the cache because their name is - * longer than NCHNAMLEN and it is not the cleanest interface, - * because there could be races. When the namei cache is re-written, - * this can be changed to use the appropriate function. - */ - else if (!(error = vnode_to_path(path, MAXPATHLEN, p->p_textvp, l, p))) - epp->ep_path = path; -#endif - else { -#ifdef notyet - printf("Cannot get path for pid %d [%s] (error %d)\n", - (int)p->p_pid, p->p_comm, error); -#endif - PNBUF_PUT(path); - epp->ep_path = NULL; - } + kmem_strfree(p->p_path); + p->p_path = kmem_strdupsize(resolvedname, NULL, KM_SLEEP); } /* XXX elsewhere */ @@ -1194,7 +1154,7 @@ execve_runproc(struct lwp *l, struct exe if (error != 0) goto exec_abort; - pathexec(epp, l, data->ed_pathstring); + pathexec(p, epp->ep_resolvedname); char * const newstack = STACK_GROW(vm->vm_minsaddr, epp->ep_ssize); @@ -1463,10 +1423,6 @@ copyoutargs(struct execve_data * restric error = (*epp->ep_esch->es_copyargs)(l, epp, &data->ed_arginfo, &newargs, data->ed_argp); - if (epp->ep_path) { - PNBUF_PUT(epp->ep_path); - epp->ep_path = NULL; - } if (error) { DPRINTF(("%s: copyargs failed %d\n", __func__, error)); return error; @@ -2258,7 +2214,7 @@ posix_spawn_fa_free(struct posix_spawn_f struct posix_spawn_file_actions_entry *fae = &fa->fae[i]; if (fae->fae_action != FAE_OPEN) continue; - kmem_free(fae->fae_path, strlen(fae->fae_path) + 1); + kmem_strfree(fae->fae_path); } if (fa->len > 0) kmem_free(fa->fae, sizeof(*fa->fae) * fa->len); Index: src/sys/kern/kern_exit.c diff -u src/sys/kern/kern_exit.c:1.269 src/sys/kern/kern_exit.c:1.270 --- src/sys/kern/kern_exit.c:1.269 Sun Aug 27 20:46:07 2017 +++ src/sys/kern/kern_exit.c Tue Nov 7 14:44:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exit.c,v 1.269 2017/08/28 00:46:07 kamil Exp $ */ +/* $NetBSD: kern_exit.c,v 1.270 2017/11/07 19:44:04 christos Exp $ */ /*- * Copyright (c) 1998, 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -67,7 +67,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.269 2017/08/28 00:46:07 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.270 2017/11/07 19:44:04 christos Exp $"); #include "opt_ktrace.h" #include "opt_dtrace.h" @@ -1250,6 +1250,7 @@ proc_free(struct proc *p, struct wrusage */ if (p->p_textvp) vrele(p->p_textvp); + kmem_strfree(p->p_path); mutex_destroy(&p->p_auxlock); mutex_obj_free(p->p_lock); Index: src/sys/kern/kern_fork.c diff -u src/sys/kern/kern_fork.c:1.202 src/sys/kern/kern_fork.c:1.203 --- src/sys/kern/kern_fork.c:1.202 Fri Apr 21 11:10:34 2017 +++ src/sys/kern/kern_fork.c Tue Nov 7 14:44:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_fork.c,v 1.202 2017/04/21 15:10:34 christos Exp $ */ +/* $NetBSD: kern_fork.c,v 1.203 2017/11/07 19:44:04 christos Exp $ */ /*- * Copyright (c) 1999, 2001, 2004, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -67,7 +67,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.202 2017/04/21 15:10:34 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_fork.c,v 1.203 2017/11/07 19:44:04 christos Exp $"); #include "opt_ktrace.h" #include "opt_dtrace.h" @@ -346,6 +346,10 @@ fork1(struct lwp *l1, int flags, int exi p2->p_textvp = p1->p_textvp; if (p2->p_textvp) vref(p2->p_textvp); + if (p1->p_path) + p2->p_path = kmem_strdupsize(p1->p_path, NULL, KM_SLEEP); + else + p2->p_path = NULL; if (flags & FORK_SHAREFILES) fd_share(p2); Index: src/sys/kern/kern_proc.c diff -u src/sys/kern/kern_proc.c:1.207 src/sys/kern/kern_proc.c:1.208 --- src/sys/kern/kern_proc.c:1.207 Sun Aug 27 20:46:07 2017 +++ src/sys/kern/kern_proc.c Tue Nov 7 14:44:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_proc.c,v 1.207 2017/08/28 00:46:07 kamil Exp $ */ +/* $NetBSD: kern_proc.c,v 1.208 2017/11/07 19:44:04 christos Exp $ */ /*- * Copyright (c) 1999, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.207 2017/08/28 00:46:07 kamil Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.208 2017/11/07 19:44:04 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_kstack.h" @@ -2433,41 +2433,28 @@ proc_find_locked(struct lwp *l, struct p static int fill_pathname(struct lwp *l, pid_t pid, void *oldp, size_t *oldlenp) { -#ifndef _RUMPKERNEL int error; struct proc *p; - char *path; - size_t len; if ((error = proc_find_locked(l, &p, pid)) != 0) return error; - if (p->p_textvp == NULL) { + if (p->p_path == NULL) { if (pid != -1) mutex_exit(p->p_lock); return ENOENT; } - path = PNBUF_GET(); - error = vnode_to_path(path, MAXPATHLEN / 2, p->p_textvp, l, p); - if (error) - goto out; - - len = strlen(path) + 1; + size_t len = strlen(p->p_path) + 1; if (oldp != NULL) { - error = sysctl_copyout(l, path, oldp, *oldlenp); + error = sysctl_copyout(l, p->p_path, oldp, *oldlenp); if (error == 0 && *oldlenp < len) error = ENOSPC; } *oldlenp = len; -out: - PNBUF_PUT(path); if (pid != -1) mutex_exit(p->p_lock); return error; -#else - return 0; -#endif } int Index: src/sys/sys/exec.h diff -u src/sys/sys/exec.h:1.151 src/sys/sys/exec.h:1.152 --- src/sys/sys/exec.h:1.151 Sat Aug 6 11:13:14 2016 +++ src/sys/sys/exec.h Tue Nov 7 14:44:05 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: exec.h,v 1.151 2016/08/06 15:13:14 maxv Exp $ */ +/* $NetBSD: exec.h,v 1.152 2017/11/07 19:44:05 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -215,7 +215,6 @@ struct exec_package { struct vnode *ep_emul_root; /* base of emulation filesystem */ struct vnode *ep_interp; /* vnode of (elf) interpeter */ uint32_t ep_pax_flags; /* pax flags */ - char *ep_path; /* absolute path of executable */ void (*ep_emul_arg_free)(void *); /* free ep_emul_arg */ uint32_t ep_osversion; /* OS version */ Index: src/sys/sys/param.h diff -u src/sys/sys/param.h:1.549 src/sys/sys/param.h:1.550 --- src/sys/sys/param.h:1.549 Mon Oct 23 07:21:56 2017 +++ src/sys/sys/param.h Tue Nov 7 14:44:05 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: param.h,v 1.549 2017/10/23 11:21:56 martin Exp $ */ +/* $NetBSD: param.h,v 1.550 2017/11/07 19:44:05 christos Exp $ */ /*- * Copyright (c) 1982, 1986, 1989, 1993 @@ -67,7 +67,7 @@ * 2.99.9 (299000900) */ -#define __NetBSD_Version__ 899000500 /* NetBSD 8.99.5 */ +#define __NetBSD_Version__ 899000600 /* NetBSD 8.99.6 */ #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \ (m) * 1000000) + (p) * 100) <= __NetBSD_Version__) Index: src/sys/sys/proc.h diff -u src/sys/sys/proc.h:1.342 src/sys/sys/proc.h:1.343 --- src/sys/sys/proc.h:1.342 Sun Aug 27 20:46:07 2017 +++ src/sys/sys/proc.h Tue Nov 7 14:44:05 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: proc.h,v 1.342 2017/08/28 00:46:07 kamil Exp $ */ +/* $NetBSD: proc.h,v 1.343 2017/11/07 19:44:05 christos Exp $ */ /*- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -315,6 +315,7 @@ struct proc { lwpid_t p_lwp_created; /* :: lwp created */ lwpid_t p_lwp_exited; /* :: lwp exited */ u_int p_nsems; /* Count of semaphores */ + char *p_path; /* :: full pathname of executable */ /* * End area that is zeroed on creation