aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64/linux32/linux32_sysvec.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2019-11-15 23:01:43 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2019-11-15 23:01:43 +0000
commit5caa67fa840e33df3a8a8edb16392116aa028ba1 (patch)
tree6c1517e8a4152b54a53d2805bfd75cd77f0e2840 /sys/amd64/linux32/linux32_sysvec.c
parent348efb140e10e96e6bd0b25878578d4ecf246434 (diff)
downloadsrc-5caa67fa840e33df3a8a8edb16392116aa028ba1.tar.gz
src-5caa67fa840e33df3a8a8edb16392116aa028ba1.zip
Use a sv_copyout_auxargs hook in the Linux ELF ABIs.
Reviewed by: emaste Tested on: amd64 (linux64 only), i386 Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D22356
Notes
Notes: svn path=/head/; revision=354754
Diffstat (limited to 'sys/amd64/linux32/linux32_sysvec.c')
-rw-r--r--sys/amd64/linux32/linux32_sysvec.c40
1 files changed, 17 insertions, 23 deletions
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index a7d886f0c42a..675834daeeab 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -185,22 +185,15 @@ linux_translate_traps(int signal, int trap_code)
}
}
-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 @@ linux_fixup_elf(register_t **stack_base, struct image_params *imgp)
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 @@ linux_copyout_strings(struct image_params *imgp)
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 @@ struct sysentvec elf_linux_sysvec = {
.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,