aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/imgact_elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/imgact_elf.c')
-rw-r--r--sys/kern/imgact_elf.c19
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);
}