Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F141220930
D22356.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D22356.diff
View Options
Index: head/sys/amd64/linux/linux_sysvec.c
===================================================================
--- head/sys/amd64/linux/linux_sysvec.c
+++ head/sys/amd64/linux/linux_sysvec.c
@@ -222,24 +222,17 @@
set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
}
-static int
-linux_fixup_elf(register_t **stack_base, struct image_params *imgp)
+static void
+linux_copyout_auxargs(struct image_params *imgp, u_long *base)
{
Elf_Auxargs *args;
Elf_Auxinfo *argarray, *pos;
- Elf_Addr *auxbase, *base;
- struct ps_strings *arginfo;
+ u_long auxlen;
struct proc *p;
- int error, issetugid;
+ int issetugid;
p = imgp->proc;
- arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
-
- KASSERT(curthread->td_proc == imgp->proc,
- ("unsafe linux_fixup_elf(), should be curproc"));
- base = (Elf64_Addr *)*stack_base;
args = (Elf64_Auxargs *)imgp->auxargs;
- auxbase = base + imgp->args->argc + 1 + imgp->args->envc + 1;
argarray = pos = malloc(LINUX_AT_COUNT * sizeof(*pos), M_TEMP,
M_WAITOK | M_ZERO);
@@ -267,15 +260,23 @@
if (args->execfd != -1)
AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd);
AUXARGS_ENTRY(pos, AT_NULL, 0);
+
free(imgp->auxargs, M_TEMP);
imgp->auxargs = NULL;
KASSERT(pos - argarray <= LINUX_AT_COUNT, ("Too many auxargs"));
- error = copyout(argarray, auxbase, sizeof(*argarray) * LINUX_AT_COUNT);
+ auxlen = sizeof(*argarray) * (pos - argarray);
+ *base -= auxlen;
+ copyout(argarray, (void *)*base, auxlen);
free(argarray, M_TEMP);
- if (error != 0)
- return (error);
+}
+static int
+linux_fixup_elf(register_t **stack_base, struct image_params *imgp)
+{
+ Elf_Addr *base;
+
+ base = (Elf64_Addr *)*stack_base;
base--;
if (suword(base, (uint64_t)imgp->args->argc) == -1)
return (EFAULT);
@@ -327,27 +328,22 @@
copyout(canary, (void *)imgp->canary, sizeof(canary));
vectp = (char **)destp;
- if (imgp->auxargs) {
- /*
- * Allocate room on the stack for the ELF auxargs
- * array. It has LINUX_AT_COUNT entries.
- */
- vectp -= howmany(LINUX_AT_COUNT * sizeof(Elf64_Auxinfo),
- sizeof(*vectp));
- }
/*
- * Allocate room for the argv[] and env vectors including the
- * terminating NULL pointers.
- */
- vectp -= imgp->args->argc + 1 + imgp->args->envc + 1;
-
- /*
* Starting with 2.24, glibc depends on a 16-byte stack alignment.
* One "long argc" will be prepended later.
*/
vectp = (char **)((((uintptr_t)vectp + 8) & ~0xF) - 8);
+ if (imgp->auxargs)
+ imgp->sysent->sv_copyout_auxargs(imgp, (u_long *)&vectp);
+
+ /*
+ * Allocate room for the argv[] and env vectors including the
+ * terminating NULL pointers.
+ */
+ vectp -= imgp->args->argc + 1 + imgp->args->envc + 1;
+
/* vectp also becomes our initial stack base. */
stack_base = (register_t *)vectp;
@@ -715,6 +711,7 @@
.sv_usrstack = USRSTACK,
.sv_psstrings = PS_STRINGS,
.sv_stackprot = VM_PROT_ALL,
+ .sv_copyout_auxargs = linux_copyout_auxargs,
.sv_copyout_strings = linux_copyout_strings,
.sv_setregs = linux_exec_setregs,
.sv_fixlimit = NULL,
Index: head/sys/amd64/linux32/linux32_sysvec.c
===================================================================
--- head/sys/amd64/linux32/linux32_sysvec.c
+++ head/sys/amd64/linux32/linux32_sysvec.c
@@ -185,22 +185,15 @@
}
}
-static int
-linux_fixup_elf(register_t **stack_base, struct image_params *imgp)
+static void
+linux_copyout_auxargs(struct image_params *imgp, u_long *base)
{
Elf32_Auxargs *args;
Elf32_Auxinfo *argarray, *pos;
- Elf32_Addr *auxbase, *base;
- struct linux32_ps_strings *arginfo;
- int error, issetugid;
+ u_long auxlen;
+ int issetugid;
- arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS;
-
- KASSERT(curthread->td_proc == imgp->proc,
- ("unsafe linux_fixup_elf(), should be curproc"));
- base = (Elf32_Addr *)*stack_base;
args = (Elf32_Auxargs *)imgp->auxargs;
- auxbase = base + (imgp->args->argc + 1 + imgp->args->envc + 1);
argarray = pos = malloc(LINUX_AT_COUNT * sizeof(*pos), M_TEMP,
M_WAITOK | M_ZERO);
@@ -244,12 +237,18 @@
imgp->auxargs = NULL;
KASSERT(pos - argarray <= LINUX_AT_COUNT, ("Too many auxargs"));
- error = copyout(&argarray[0], auxbase,
- sizeof(*argarray) * LINUX_AT_COUNT);
+ auxlen = sizeof(*argarray) * (pos - argarray);
+ *base -= auxlen;
+ copyout(argarray, (void *)*base, auxlen);
free(argarray, M_TEMP);
- if (error != 0)
- return (error);
+}
+static int
+linux_fixup_elf(register_t **stack_base, struct image_params *imgp)
+{
+ Elf32_Addr *base;
+
+ base = (Elf32_Addr *)*stack_base;
base--;
if (suword32(base, (uint32_t)imgp->args->argc) == -1)
return (EFAULT);
@@ -755,14 +754,8 @@
copyout(canary, (void *)imgp->canary, sizeof(canary));
vectp = (uint32_t *)destp;
- if (imgp->auxargs) {
- /*
- * Allocate room on the stack for the ELF auxargs
- * array. It has LINUX_AT_COUNT entries.
- */
- vectp -= howmany(LINUX_AT_COUNT * sizeof(Elf32_Auxinfo),
- sizeof(*vectp));
- }
+ if (imgp->auxargs)
+ imgp->sysent->sv_copyout_auxargs(imgp, (u_long *)&vectp);
/*
* Allocate room for the argv[] and env vectors including the
@@ -875,6 +868,7 @@
.sv_usrstack = LINUX32_USRSTACK,
.sv_psstrings = LINUX32_PS_STRINGS,
.sv_stackprot = VM_PROT_ALL,
+ .sv_copyout_auxargs = linux_copyout_auxargs,
.sv_copyout_strings = linux_copyout_strings,
.sv_setregs = linux_exec_setregs,
.sv_fixlimit = linux32_fixlimit,
Index: head/sys/arm64/linux/linux_sysvec.c
===================================================================
--- head/sys/arm64/linux/linux_sysvec.c
+++ head/sys/arm64/linux/linux_sysvec.c
@@ -87,6 +87,7 @@
/* DTrace probes */
LIN_SDT_PROBE_DEFINE2(sysvec, linux_translate_traps, todo, "int", "int");
LIN_SDT_PROBE_DEFINE0(sysvec, linux_exec_setregs, todo);
+LIN_SDT_PROBE_DEFINE0(sysvec, linux_copyout_auxargs, todo);
LIN_SDT_PROBE_DEFINE0(sysvec, linux_elf_fixup, todo);
LIN_SDT_PROBE_DEFINE0(sysvec, linux_rt_sigreturn, todo);
LIN_SDT_PROBE_DEFINE0(sysvec, linux_rt_sendsig, todo);
@@ -140,26 +141,19 @@
cpu_set_syscall_retval(td, error);
}
-static int
-linux_elf_fixup(register_t **stack_base, struct image_params *imgp)
+static void
+linux_copyout_auxargs(struct image_params *imgp, u_long *base)
{
Elf_Auxargs *args;
Elf_Auxinfo *argarray, *pos;
- Elf_Addr *auxbase, *base;
- struct ps_strings *arginfo;
+ u_long auxlen;
struct proc *p;
- int error, issetugid;
+ int issetugid;
- LIN_SDT_PROBE0(sysvec, linux_elf_fixup, todo);
+ LIN_SDT_PROBE0(sysvec, linux_copyout_auxargs, todo);
p = imgp->proc;
- arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
- KASSERT(curthread->td_proc == imgp->proc,
- ("unsafe linux_elf_fixup(), should be curproc"));
- base = (Elf64_Addr *)*stack_base;
args = (Elf64_Auxargs *)imgp->auxargs;
- /* Auxargs after argc, and NULL-terminated argv and envv lists. */
- auxbase = base + 1 + imgp->args->argc + 1 + imgp->args->envc + 1;
argarray = pos = malloc(LINUX_AT_COUNT * sizeof(*pos), M_TEMP,
M_WAITOK | M_ZERO);
@@ -195,11 +189,18 @@
imgp->auxargs = NULL;
KASSERT(pos - argarray <= LINUX_AT_COUNT, ("Too many auxargs"));
- error = copyout(argarray, auxbase, sizeof(*argarray) * LINUX_AT_COUNT);
+ auxlen = sizeof(*argarray) * (pos - argarray);
+ *base -= auxlen;
+ copyout(argarray, (void *)*base, auxlen);
free(argarray, M_TEMP);
- if (error != 0)
- return (error);
+}
+static int
+linux_elf_fixup(register_t **stack_base, struct image_params *imgp)
+{
+
+ LIN_SDT_PROBE0(sysvec, linux_elf_fixup, todo);
+
return (0);
}
@@ -247,14 +248,8 @@
copyout(canary, (void *)imgp->canary, sizeof(canary));
vectp = (char **)destp;
- if (imgp->auxargs) {
- /*
- * Allocate room on the stack for the ELF auxargs
- * array. It has up to LINUX_AT_COUNT entries.
- */
- vectp -= howmany(LINUX_AT_COUNT * sizeof(Elf64_Auxinfo),
- sizeof(*vectp));
- }
+ if (imgp->auxargs)
+ imgp->sysent->sv_copyout_auxargs(imgp, (u_long *)&vectp);
/*
* Allocate room for argc and the argv[] and env vectors including the
@@ -372,6 +367,7 @@
.sv_usrstack = USRSTACK,
.sv_psstrings = PS_STRINGS, /* XXX */
.sv_stackprot = VM_PROT_READ | VM_PROT_WRITE,
+ .sv_copyout_auxargs = linux_copyout_auxargs,
.sv_copyout_strings = linux_copyout_strings,
.sv_setregs = linux_exec_setregs,
.sv_fixlimit = NULL,
Index: head/sys/i386/linux/linux_sysvec.c
===================================================================
--- head/sys/i386/linux/linux_sysvec.c
+++ head/sys/i386/linux/linux_sysvec.c
@@ -188,25 +188,22 @@
return (0);
}
-static int
-linux_fixup_elf(register_t **stack_base, struct image_params *imgp)
+static void
+linux_copyout_auxargs(struct image_params *imgp, u_long *base)
{
struct proc *p;
Elf32_Auxargs *args;
Elf32_Auxinfo *argarray, *pos;
- Elf32_Addr *auxbase, *uplatform;
+ Elf32_Addr *uplatform;
struct ps_strings *arginfo;
- int error, issetugid;
+ u_long auxlen;
+ int issetugid;
- KASSERT(curthread->td_proc == imgp->proc,
- ("unsafe linux_fixup_elf(), should be curproc"));
-
p = imgp->proc;
issetugid = imgp->proc->p_flag & P_SUGID ? 1 : 0;
arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
uplatform = (Elf32_Addr *)((caddr_t)arginfo - linux_szplatform);
args = (Elf32_Auxargs *)imgp->auxargs;
- auxbase = *stack_base + imgp->args->argc + 1 + imgp->args->envc + 1;
argarray = pos = malloc(LINUX_AT_COUNT * sizeof(*pos), M_TEMP,
M_WAITOK | M_ZERO);
@@ -249,11 +246,16 @@
imgp->auxargs = NULL;
KASSERT(pos - argarray <= LINUX_AT_COUNT, ("Too many auxargs"));
- error = copyout(argarray, auxbase, sizeof(*argarray) * LINUX_AT_COUNT);
+ auxlen = sizeof(*argarray) * (pos - argarray);
+ *base -= auxlen;
+ copyout(argarray, (void *)*base, auxlen);
free(argarray, M_TEMP);
- if (error != 0)
- return (error);
+}
+static int
+linux_fixup_elf(register_t **stack_base, struct image_params *imgp)
+{
+
(*stack_base)--;
if (suword(*stack_base, (register_t)imgp->args->argc) == -1)
return (EFAULT);
@@ -305,14 +307,8 @@
copyout(canary, (void *)imgp->canary, sizeof(canary));
vectp = (char **)destp;
- if (imgp->auxargs) {
- /*
- * Allocate room on the stack for the ELF auxargs
- * array. It has LINUX_AT_COUNT entries.
- */
- vectp -= howmany(LINUX_AT_COUNT * sizeof(Elf32_Auxinfo),
- sizeof(*vectp));
- }
+ if (imgp->auxargs)
+ imgp->sysent->sv_copyout_auxargs(imgp, (u_long *)&vectp);
/*
* Allocate room for the argv[] and env vectors including the
@@ -851,6 +847,7 @@
.sv_usrstack = LINUX_USRSTACK,
.sv_psstrings = LINUX_PS_STRINGS,
.sv_stackprot = VM_PROT_ALL,
+ .sv_copyout_auxargs = linux_copyout_auxargs,
.sv_copyout_strings = linux_copyout_strings,
.sv_setregs = linux_exec_setregs,
.sv_fixlimit = NULL,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jan 3, 2:29 PM (1 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27472657
Default Alt Text
D22356.diff (10 KB)
Attached To
Mode
D22356: Use a sv_copyout_auxargs hook in the Linux ELF ABIs.
Attached
Detach File
Event Timeline
Log In to Comment