aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2019-12-09 19:17:28 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2019-12-09 19:17:28 +0000
commitd8010b1175094374c8295d0fba56c2402b32a4da (patch)
treec7ec23282e906cef00c1d82b37a46999f306a45d /sys/kern
parent168bde45c2d527f3bc70345ce33d48273ecf73a1 (diff)
downloadsrc-d8010b1175094374c8295d0fba56c2402b32a4da.tar.gz
src-d8010b1175094374c8295d0fba56c2402b32a4da.zip
Copy out aux args after the argument and environment vectors.
Partially revert r354741 and r354754 and go back to allocating a fixed-size chunk of stack space for the auxiliary vector. Keep sv_copyout_auxargs but change it to accept the address at the end of the environment vector as an input stack address and no longer allocate room on the stack. It is now called at the end of copyout_strings after the argv and environment vectors have been copied out. This should fix a regression in r354754 that broke the stack alignment for newer Linux amd64 binaries (and probably broke Linux arm64 as well). Reviewed by: kib Tested on: amd64 (native, linux64 (only linux-base-c7), and i386) Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D22695
Notes
Notes: svn path=/head/; revision=355567
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/imgact_elf.c7
-rw-r--r--sys/kern/kern_exec.c17
2 files changed, 16 insertions, 8 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index ebd3a45e5ba4..7ce86fbea5a7 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -1324,11 +1324,10 @@ ret:
#define suword __CONCAT(suword, __ELF_WORD_SIZE)
int
-__elfN(freebsd_copyout_auxargs)(struct image_params *imgp, uintptr_t *base)
+__elfN(freebsd_copyout_auxargs)(struct image_params *imgp, uintptr_t base)
{
Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs;
Elf_Auxinfo *argarray, *pos;
- u_long auxlen;
int error;
argarray = pos = malloc(AT_COUNT * sizeof(*pos), M_TEMP,
@@ -1374,9 +1373,7 @@ __elfN(freebsd_copyout_auxargs)(struct image_params *imgp, uintptr_t *base)
imgp->auxargs = NULL;
KASSERT(pos - argarray <= AT_COUNT, ("Too many auxargs"));
- auxlen = sizeof(*argarray) * (pos - argarray);
- *base -= auxlen;
- error = copyout(argarray, (void *)*base, auxlen);
+ error = copyout(argarray, (void *)base, sizeof(*argarray) * AT_COUNT);
free(argarray, M_TEMP);
return (error);
}
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index e2611ba6f944..aaf08183e868 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -1661,9 +1661,12 @@ exec_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
imgp->sysent->sv_stackgap(imgp, &destp);
if (imgp->auxargs) {
- error = imgp->sysent->sv_copyout_auxargs(imgp, &destp);
- if (error != 0)
- return (error);
+ /*
+ * Allocate room on the stack for the ELF auxargs
+ * array. It has up to AT_COUNT entries.
+ */
+ destp -= AT_COUNT * sizeof(Elf_Auxinfo);
+ destp = rounddown2(destp, sizeof(void *));
}
vectp = (char **)destp;
@@ -1732,6 +1735,14 @@ exec_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
if (suword(vectp, 0) != 0)
return (EFAULT);
+ if (imgp->auxargs) {
+ vectp++;
+ error = imgp->sysent->sv_copyout_auxargs(imgp,
+ (uintptr_t)vectp);
+ if (error != 0)
+ return (error);
+ }
+
return (0);
}