diff options
Diffstat (limited to 'sys/kern/imgact_elf.c')
-rw-r--r-- | sys/kern/imgact_elf.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 83c9886bee67..36217fc6e914 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -1098,11 +1098,14 @@ int __elfN(freebsd_fixup)(register_t **stack_base, struct image_params *imgp) { Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs; - Elf_Addr *base; - Elf_Addr *pos; + Elf_Auxinfo *argarray, *pos; + Elf_Addr *base, *auxbase; + int error; base = (Elf_Addr *)*stack_base; - pos = base + (imgp->args->argc + imgp->args->envc + 2); + auxbase = base + imgp->args->argc + 1 + imgp->args->envc + 1; + argarray = pos = malloc(AT_COUNT * sizeof(*pos), M_TEMP, + M_WAITOK | M_ZERO); if (args->execfd != -1) AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); @@ -1142,9 +1145,17 @@ __elfN(freebsd_fixup)(register_t **stack_base, struct image_params *imgp) free(imgp->auxargs, M_TEMP); imgp->auxargs = NULL; + KASSERT((pos - argarray) / sizeof(*pos) <= AT_COUNT, + ("Too many auxargs")); + + error = copyout(argarray, auxbase, sizeof(*argarray) * AT_COUNT); + free(argarray, M_TEMP); + if (error != 0) + return (error); base--; - suword(base, (long)imgp->args->argc); + if (suword(base, imgp->args->argc) == -1) + return (EFAULT); *stack_base = (register_t *)base; return (0); } |