summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/compat/ia32/ia32_sysvec.c21
-rw-r--r--sys/kern/imgact_elf.c2
-rw-r--r--sys/kern/kern_exec.c31
-rw-r--r--sys/sys/imgact.h3
4 files changed, 52 insertions, 5 deletions
diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c
index e5d8828..2b7ecba 100644
--- a/sys/compat/ia32/ia32_sysvec.c
+++ b/sys/compat/ia32/ia32_sysvec.c
@@ -189,15 +189,21 @@ ia32_copyout_strings(struct image_params *imgp)
char *stringp, *destp;
u_int32_t *stack_base;
struct freebsd32_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 freebsd32_ps_strings *)FREEBSD32_PS_STRINGS;
szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
+ roundup(execpath_len, sizeof(char *)) -
roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
/*
@@ -208,6 +214,15 @@ ia32_copyout_strings(struct image_params *imgp)
((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.
*/
@@ -223,9 +238,9 @@ ia32_copyout_strings(struct image_params *imgp)
* the arg and env vector sets,and imgp->auxarg_size is room
* for argument of Runtime loader.
*/
- vectp = (u_int32_t *) (destp - (imgp->args->argc + imgp->args->envc + 2 +
- imgp->auxarg_size) * sizeof(u_int32_t));
-
+ vectp = (u_int32_t *) (destp - (imgp->args->argc +
+ imgp->args->envc + 2 + imgp->auxarg_size + execpath_len) *
+ sizeof(u_int32_t));
} else
/*
* The '+ 2' is for the null pointers at the end of each of
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 5604ea5..3039011 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -885,6 +885,8 @@ __elfN(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);
free(imgp->auxargs, M_TEMP);
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index af6c9e4..f36f803 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -379,6 +379,8 @@ do_execve(td, args, mac_p)
imgp->ps_strings = 0;
imgp->auxarg_size = 0;
imgp->args = args;
+ imgp->execpath = imgp->freepath = NULL;
+ imgp->execpathp = 0;
#ifdef MAC
error = mac_execve_enter(imgp, mac_p);
@@ -519,6 +521,15 @@ interpret:
* of the sv_copyout_strings/sv_fixup operations require the vnode.
*/
VOP_UNLOCK(imgp->vp, 0);
+
+ /*
+ * Do the best to calculate the full path to the image file.
+ */
+ if (imgp->auxargs != NULL &&
+ ((args->fname != NULL && args->fname[0] == '/') ||
+ vn_fullpath(td, imgp->vp, &imgp->execpath, &imgp->freepath) != 0))
+ imgp->execpath = args->fname;
+
/*
* Copy out strings (args and env) and initialize stack base
*/
@@ -859,6 +870,8 @@ exec_fail_dealloc:
if (imgp->object != NULL)
vm_object_deallocate(imgp->object);
+ free(imgp->freepath, M_TEMP);
+
if (error == 0) {
/*
* Stop the process here if its stop event mask has
@@ -1164,18 +1177,24 @@ exec_copyout_strings(imgp)
register_t *stack_base;
struct ps_strings *arginfo;
struct proc *p;
+ 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;
p = imgp->proc;
szsigcode = 0;
arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
if (p->p_sysent->sv_szsigcode != NULL)
szsigcode = *(p->p_sysent->sv_szsigcode);
destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
+ roundup(execpath_len, sizeof(char *)) -
roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
/*
@@ -1186,6 +1205,15 @@ exec_copyout_strings(imgp)
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.
*/
@@ -1202,9 +1230,8 @@ exec_copyout_strings(imgp)
* for argument of Runtime loader.
*/
vectp = (char **)(destp - (imgp->args->argc +
- imgp->args->envc + 2 + imgp->auxarg_size) *
+ imgp->args->envc + 2 + imgp->auxarg_size + execpath_len) *
sizeof(char *));
-
} else {
/*
* The '+ 2' is for the null pointers at the end of each of
diff --git a/sys/sys/imgact.h b/sys/sys/imgact.h
index 011a7ae..e6acc00 100644
--- a/sys/sys/imgact.h
+++ b/sys/sys/imgact.h
@@ -66,6 +66,9 @@ struct image_params {
size_t auxarg_size;
struct image_args *args; /* system call arguments */
struct sysentvec *sysent; /* system entry vector */
+ char *execpath;
+ unsigned long execpathp;
+ char *freepath;
};
#ifdef _KERNEL
OpenPOWER on IntegriCloud