From adc42cf35b64fcc5e902e062955772f363e1ec58 Mon Sep 17 00:00:00 2001 From: John Marino Date: Sat, 23 Apr 2011 21:44:10 +0200 Subject: [PATCH] kernel: Implement ELF auxinfo entry type AT_EXECPATH Refer to issue 2005. The new RTLD can optionally use AT_EXECPATH for some of its new functionality such as libmap.conf and dynamic token expansion. In the absence of this kernel support, RTLD has a fallback mechanism that works most of the time, but using it takes a performance hit. This patch was tested for some time by various people prior to the 2.10 branch being created. --- sys/kern/imgact_elf.c | 2 ++ sys/kern/kern_exec.c | 37 +++++++++++++++++++++++++++++++++++-- sys/sys/imgact.h | 3 +++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 72d3ef1efc..099d1db56e 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -926,6 +926,8 @@ elf_freebsd_fixup(register_t **stack_base, struct image_params *imgp) AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); AUXARGS_ENTRY(pos, AT_BASE, args->base); + if (imgp->execpathp != 0) + AUXARGS_ENTRY(pos, AT_EXECPATH, imgp->execpathp); AUXARGS_ENTRY(pos, AT_NULL, 0); kfree(imgp->auxargs, M_TEMP); diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 6174a93c8d..f27d4e1ed0 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -24,7 +24,6 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/kern/kern_exec.c,v 1.107.2.15 2002/07/30 15:40:46 nectar Exp $ - * $DragonFly: src/sys/kern/kern_exec.c,v 1.64 2008/10/26 04:29:19 sephe Exp $ */ #include @@ -222,6 +221,8 @@ kern_execve(struct nlookupdata *nd, struct image_args *args) imgp->vp = NULL; imgp->firstpage = NULL; imgp->ps_strings = 0; + imgp->execpath = imgp->freepath = NULL; + imgp->execpathp = 0; imgp->image_header = NULL; interpret: @@ -311,6 +312,18 @@ interpret: goto interpret; } + /* + * Do the best to calculate the full path to the image file + */ + if (imgp->auxargs != NULL && + ((args->fname != NULL && args->fname[0] == '/') || + vn_fullpath(imgp->proc, + imgp->vp, + &imgp->execpath, + &imgp->freepath, + 0) != 0)) + imgp->execpath = args->fname; + /* * Copy out strings (args and env) and initialize stack base */ @@ -533,6 +546,9 @@ exec_fail_dealloc: return (0); } + if (imgp->freepath) + kfree(imgp->freepath, M_TEMP); + exec_fail: /* * we're done here, clear P_INEXEC if we were the ones that @@ -894,12 +910,17 @@ exec_copyout_strings(struct image_params *imgp) char *stringp, *destp; register_t *stack_base; struct ps_strings *arginfo; + size_t execpath_len; int szsigcode; /* * Calculate string base and vector table pointers. * Also deal with signal trampoline code for this exec type. */ + if (imgp->execpath != NULL && imgp->auxargs != NULL) + execpath_len = strlen(imgp->execpath) + 1; + else + execpath_len = 0; arginfo = (struct ps_strings *)PS_STRINGS; szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); if (stackgap_random != 0) @@ -907,6 +928,7 @@ exec_copyout_strings(struct image_params *imgp) else sgap = 0; destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - sgap - + roundup(execpath_len, sizeof(char *)) - roundup((ARG_MAX - imgp->args->space), sizeof(char *)); /* @@ -916,6 +938,16 @@ exec_copyout_strings(struct image_params *imgp) copyout(imgp->proc->p_sysent->sv_sigcode, ((caddr_t)arginfo - szsigcode), szsigcode); + /* + * Copy the image path for the rtld + */ + if (execpath_len != 0) { + imgp->execpathp = (uintptr_t)arginfo + - szsigcode + - execpath_len; + copyout(imgp->execpath, (void *)imgp->execpathp, execpath_len); + } + /* * If we have a valid auxargs ptr, prepare some room * on the stack. @@ -926,7 +958,8 @@ exec_copyout_strings(struct image_params *imgp) */ if (imgp->auxargs) { vectp = (char **)(destp - (imgp->args->argc + - imgp->args->envc + 2 + AT_COUNT * 2) * sizeof(char*)); + imgp->args->envc + 2 + (AT_COUNT * 2) + execpath_len) * + sizeof(char*)); } else { vectp = (char **)(destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(char*)); diff --git a/sys/sys/imgact.h b/sys/sys/imgact.h index 40ca7c3088..18e9f6e7aa 100644 --- a/sys/sys/imgact.h +++ b/sys/sys/imgact.h @@ -68,6 +68,9 @@ struct image_params { struct lwbuf *firstpage; /* first page that we mapped */ struct lwbuf firstpage_cache; unsigned long ps_strings; /* PS_STRINGS for BSD/OS binaries */ + char *execpath; + unsigned long execpathp; + char *freepath; }; #ifdef _KERNEL -- 2.41.0