diff options
author | John Baldwin <jhb@FreeBSD.org> | 2019-11-15 23:01:43 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2019-11-15 23:01:43 +0000 |
commit | 5caa67fa840e33df3a8a8edb16392116aa028ba1 (patch) | |
tree | 6c1517e8a4152b54a53d2805bfd75cd77f0e2840 /sys/amd64/linux32/linux32_sysvec.c | |
parent | 348efb140e10e96e6bd0b25878578d4ecf246434 (diff) | |
download | src-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.c | 40 |
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, |