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/amd64/linux32/linux32_sysvec.c | |
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/amd64/linux32/linux32_sysvec.c')
-rw-r--r-- | sys/amd64/linux32/linux32_sysvec.c | 66 |
1 files changed, 36 insertions, 30 deletions
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index ba87152d7a9a..a08372b66add 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -101,13 +101,13 @@ extern struct sysent linux32_sysent[LINUX32_SYS_MAXSYSCALL]; SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler); -static int linux_fixup_elf(register_t **stack_base, +static int linux_fixup_elf(uintptr_t *stack_base, struct image_params *iparams); static int linux_copyout_strings(struct image_params *imgp, - register_t **stack_base); + uintptr_t *stack_base); 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 void linux32_fixlimit(struct rlimit *rl, int which); static bool linux32_trans_osrel(const Elf_Note *note, int32_t *osrel); static void linux_vdso_install(void *param); @@ -246,7 +246,7 @@ 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) { Elf32_Addr *base; @@ -254,7 +254,7 @@ linux_fixup_elf(register_t **stack_base, struct image_params *imgp) base--; if (suword32(base, (uint32_t)imgp->args->argc) == -1) return (EFAULT); - *stack_base = (register_t *)base; + *stack_base = (uintptr_t)base; return (0); } @@ -677,7 +677,8 @@ linux32_fetch_syscall_args(struct thread *td) * XXX copied from ia32_signal.c. */ 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 trapframe *regs = td->td_frame; struct pcb *pcb = td->td_pcb; @@ -721,11 +722,12 @@ linux_exec_setregs(struct thread *td, struct image_params *imgp, u_long stack) * XXX copied from ia32_sysvec.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; u_int32_t *vectp; - char *stringp, *destp; + char *stringp; + uintptr_t destp, ustringp; struct linux32_ps_strings *arginfo; char canary[LINUX_AT_RANDOM_LEN]; size_t execpath_len; @@ -737,36 +739,38 @@ linux_copyout_strings(struct image_params *imgp, register_t **stack_base) execpath_len = 0; arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS; - destp = (caddr_t)arginfo - SPARE_USRSPACE - - roundup(sizeof(canary), sizeof(char *)) - - roundup(execpath_len, sizeof(char *)) - - roundup(ARG_MAX - imgp->args->stringspace, sizeof(char *)); + destp = (uintptr_t)arginfo; if (execpath_len != 0) { - imgp->execpathp = (uintptr_t)arginfo - 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 - - 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 = (uint32_t *)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 = (uint32_t *)destp; + /* * Allocate room for the argv[] and env vectors including the * terminating NULL pointers. @@ -774,13 +778,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); @@ -791,11 +797,11 @@ linux_copyout_strings(struct image_params *imgp, register_t **stack_base) /* Fill in argument portion of vector table. */ for (; argc > 0; --argc) { - if (suword32(vectp++, (uint32_t)(intptr_t)destp) != 0) + if (suword32(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. */ @@ -808,11 +814,11 @@ linux_copyout_strings(struct image_params *imgp, register_t **stack_base) /* Fill in environment portion of vector table. */ for (; envc > 0; --envc) { - if (suword32(vectp++, (uint32_t)(intptr_t)destp) != 0) + if (suword32(vectp++, ustringp) != 0) return (EFAULT); while (*stringp++ != 0) - destp++; - destp++; + ustringp++; + ustringp++; } /* The end of the vector table is a null pointer. */ |