diff options
author | John Baldwin <jhb@FreeBSD.org> | 2019-12-03 23:17:54 +0000 |
---|---|---|
committer | John Baldwin <jhb@FreeBSD.org> | 2019-12-03 23:17:54 +0000 |
commit | 31174518d2db4950b8bc8ab02e64cdb5e00d34c9 (patch) | |
tree | 2c830969197705d2f745734684051163c5b29ec5 /sys/i386 | |
parent | d00066a5f923073113bcb0213ca7a0a9a29b9561 (diff) | |
download | src-31174518d2db4950b8bc8ab02e64cdb5e00d34c9.tar.gz src-31174518d2db4950b8bc8ab02e64cdb5e00d34c9.zip |
Use uintptr_t instead of register_t * for the stack base.
- Use ustringp for the location of the argv and environment strings
and allow destp to travel further down the stack for the stackgap
and auxv regions.
- Update the Linux copyout_strings variants to move destp down the
stack as was done for the native ABIs in r263349.
- Stop allocating a space for a stack gap in the Linux ABIs. This
used to hold translated system call arguments, but hasn't been used
since r159992.
Reviewed by: kib
Tested on: md64 (amd64, i386, linux64), i386 (i386, linux)
Sponsored by: DARPA
Differential Revision: https://reviews.freebsd.org/D22501
Notes
Notes:
svn path=/head/; revision=355373
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/cloudabi32/cloudabi32_sysvec.c | 12 | ||||
-rw-r--r-- | sys/i386/i386/machdep.c | 2 | ||||
-rw-r--r-- | sys/i386/linux/linux_sysvec.c | 104 |
3 files changed, 64 insertions, 54 deletions
diff --git a/sys/i386/cloudabi32/cloudabi32_sysvec.c b/sys/i386/cloudabi32/cloudabi32_sysvec.c index 31035a121f01..76cab063501d 100644 --- a/sys/i386/cloudabi32/cloudabi32_sysvec.c +++ b/sys/i386/cloudabi32/cloudabi32_sysvec.c @@ -48,7 +48,7 @@ extern const char *cloudabi32_syscallnames[]; extern struct sysent cloudabi32_sysent[]; static int -cloudabi32_fixup_tcb(register_t **stack_base, struct image_params *imgp) +cloudabi32_fixup_tcb(uintptr_t *stack_base, struct image_params *imgp) { int error; uint32_t args[2]; @@ -68,16 +68,16 @@ cloudabi32_fixup_tcb(register_t **stack_base, struct image_params *imgp) * refer to the auxiliary vector, which is stored right after * the TCB. */ - args[0] = (uintptr_t)*stack_base; - args[1] = (uintptr_t)*stack_base + + args[0] = *stack_base; + args[1] = *stack_base + roundup(sizeof(cloudabi32_tcb_t), sizeof(register_t)); - *stack_base -= howmany(sizeof(args), sizeof(register_t)); - return (copyout(args, *stack_base, sizeof(args))); + *stack_base -= roundup(sizeof(args), sizeof(register_t)); + return (copyout(args, (void *)*stack_base, sizeof(args))); } static void cloudabi32_proc_setregs(struct thread *td, struct image_params *imgp, - unsigned long stack) + uintptr_t stack) { exec_setregs(td, imgp, stack); diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 77ab78b526a1..60ebb3a3510e 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -1124,7 +1124,7 @@ setup_priv_lcall_gate(struct proc *p) * Reset registers to default values on exec. */ void -exec_setregs(struct thread *td, struct image_params *imgp, u_long stack) +exec_setregs(struct thread *td, struct image_params *imgp, uintptr_t stack) { struct trapframe *regs; struct pcb *pcb; diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 787fb83c534b..e067e1f82123 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -88,15 +88,15 @@ extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler); -static int linux_fixup(register_t **stack_base, +static int linux_fixup(uintptr_t *stack_base, struct image_params *iparams); -static int linux_fixup_elf(register_t **stack_base, +static int linux_fixup_elf(uintptr_t *stack_base, struct image_params *iparams); static void linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask); static void linux_exec_setregs(struct thread *td, - struct image_params *imgp, u_long stack); + struct image_params *imgp, uintptr_t stack); static int linux_copyout_strings(struct image_params *imgp, - register_t **stack_base); + uintptr_t *stack_base); static bool linux_trans_osrel(const Elf_Note *note, int32_t *osrel); static void linux_vdso_install(void *param); static void linux_vdso_deinstall(void *param); @@ -174,23 +174,25 @@ linux_translate_traps(int signal, int trap_code) } static int -linux_fixup(register_t **stack_base, struct image_params *imgp) +linux_fixup(uintptr_t *stack_base, struct image_params *imgp) { - register_t *argv, *envp; - - argv = *stack_base; - envp = *stack_base + (imgp->args->argc + 1); - (*stack_base)--; - suword(*stack_base, (intptr_t)(void *)envp); - (*stack_base)--; - suword(*stack_base, (intptr_t)(void *)argv); - (*stack_base)--; - suword(*stack_base, imgp->args->argc); + register_t *base, *argv, *envp; + + base = (register_t *)*stack_base; + argv = base; + envp = base + (imgp->args->argc + 1); + base--; + suword(base, (intptr_t)envp); + base--; + suword(base, (intptr_t)argv); + base--; + suword(base, imgp->args->argc); + *stack_base = (uintptr_t)base; return (0); } static int -linux_copyout_auxargs(struct image_params *imgp, u_long *base) +linux_copyout_auxargs(struct image_params *imgp, uintptr_t *base) { struct proc *p; Elf32_Auxargs *args; @@ -255,12 +257,15 @@ linux_copyout_auxargs(struct image_params *imgp, u_long *base) } static int -linux_fixup_elf(register_t **stack_base, struct image_params *imgp) +linux_fixup_elf(uintptr_t *stack_base, struct image_params *imgp) { + register_t *base; - (*stack_base)--; - if (suword(*stack_base, (register_t)imgp->args->argc) == -1) + base = (register_t *)*stack_base; + base--; + if (suword(base, (register_t)imgp->args->argc) == -1) return (EFAULT); + *stack_base = (uintptr_t)base; return (0); } @@ -268,11 +273,12 @@ linux_fixup_elf(register_t **stack_base, struct image_params *imgp) * Copied from kern/kern_exec.c */ static int -linux_copyout_strings(struct image_params *imgp, register_t **stack_base) +linux_copyout_strings(struct image_params *imgp, uintptr_t *stack_base) { int argc, envc, error; char **vectp; - char *stringp, *destp; + char *stringp; + uintptr_t destp, ustringp; struct ps_strings *arginfo; char canary[LINUX_AT_RANDOM_LEN]; size_t execpath_len; @@ -285,43 +291,45 @@ linux_copyout_strings(struct image_params *imgp, register_t **stack_base) else execpath_len = 0; arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings; - destp = (caddr_t)arginfo - SPARE_USRSPACE - linux_szplatform - - roundup(sizeof(canary), sizeof(char *)) - - roundup(execpath_len, sizeof(char *)) - - roundup(ARG_MAX - imgp->args->stringspace, sizeof(char *)); + destp = (uintptr_t)arginfo; /* Install LINUX_PLATFORM. */ - error = copyout(linux_kplatform, ((caddr_t)arginfo - linux_szplatform), - linux_szplatform); + destp -= linux_szplatform; + destp = rounddown2(destp, sizeof(void *)); + error = copyout(linux_kplatform, (void *)destp, linux_szplatform); if (error != 0) return (error); if (execpath_len != 0) { - imgp->execpathp = (uintptr_t)arginfo - - linux_szplatform - execpath_len; - error = copyout(imgp->execpath, (void *)imgp->execpathp, - execpath_len); + destp -= execpath_len; + destp = rounddown2(destp, sizeof(void *)); + imgp->execpathp = destp; + error = copyout(imgp->execpath, (void *)destp, execpath_len); if (error != 0) return (error); } /* Prepare the canary for SSP. */ arc4rand(canary, sizeof(canary), 0); - imgp->canary = (uintptr_t)arginfo - linux_szplatform - - roundup(execpath_len, sizeof(char *)) - - roundup(sizeof(canary), sizeof(char *)); - error = copyout(canary, (void *)imgp->canary, sizeof(canary)); + destp -= roundup(sizeof(canary), sizeof(void *)); + imgp->canary = destp; + error = copyout(canary, (void *)destp, sizeof(canary)); if (error != 0) return (error); - vectp = (char **)destp; + /* Allocate room for the argument and environment strings. */ + destp -= ARG_MAX - imgp->args->stringspace; + destp = rounddown2(destp, sizeof(void *)); + ustringp = destp; + if (imgp->auxargs) { - error = imgp->sysent->sv_copyout_auxargs(imgp, - (u_long *)&vectp); + error = imgp->sysent->sv_copyout_auxargs(imgp, &destp); if (error != 0) return (error); } + vectp = (char **)destp; + /* * Allocate room for the argv[] and env vectors including the * terminating NULL pointers. @@ -329,14 +337,15 @@ linux_copyout_strings(struct image_params *imgp, register_t **stack_base) vectp -= imgp->args->argc + 1 + imgp->args->envc + 1; /* vectp also becomes our initial stack base. */ - *stack_base = (register_t *)vectp; + *stack_base = (uintptr_t)vectp; stringp = imgp->args->begin_argv; argc = imgp->args->argc; envc = imgp->args->envc; /* Copy out strings - arguments and environment. */ - error = copyout(stringp, destp, ARG_MAX - imgp->args->stringspace); + error = copyout(stringp, (void *)ustringp, + ARG_MAX - imgp->args->stringspace); if (error != 0) return (error); @@ -347,11 +356,11 @@ linux_copyout_strings(struct image_params *imgp, register_t **stack_base) /* Fill in argument portion of vector table. */ for (; argc > 0; --argc) { - if (suword(vectp++, (long)(intptr_t)destp) != 0) + if (suword(vectp++, ustringp) != 0) return (EFAULT); while (*stringp++ != 0) - destp++; - destp++; + ustringp++; + ustringp++; } /* A null vector table pointer separates the argp's from the envp's. */ @@ -364,11 +373,11 @@ linux_copyout_strings(struct image_params *imgp, register_t **stack_base) /* Fill in environment portion of vector table. */ for (; envc > 0; --envc) { - if (suword(vectp++, (long)(intptr_t)destp) != 0) + if (suword(vectp++, ustringp) != 0) return (EFAULT); while (*stringp++ != 0) - destp++; - destp++; + ustringp++; + ustringp++; } /* The end of the vector table is a null pointer. */ @@ -781,7 +790,8 @@ linux_fetch_syscall_args(struct thread *td) * override the exec_setregs default(s) here. */ static void -linux_exec_setregs(struct thread *td, struct image_params *imgp, u_long stack) +linux_exec_setregs(struct thread *td, struct image_params *imgp, + uintptr_t stack) { struct pcb *pcb = td->td_pcb; |