diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/imgact_elf.c | 7 | ||||
-rw-r--r-- | sys/kern/kern_exec.c | 17 |
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); } |