diff options
| author | John Baldwin <jhb@FreeBSD.org> | 2019-11-18 20:07:43 +0000 |
|---|---|---|
| committer | John Baldwin <jhb@FreeBSD.org> | 2019-11-18 20:07:43 +0000 |
| commit | 03b0d68c7237a1610185bf8adbcdcc51cc1c3823 (patch) | |
| tree | 2fcea92c35e69703d2128f14eb0513c93916f66d /sys/amd64/linux32 | |
| parent | 85e06c728c68131e155a5e7138bec7f300d82433 (diff) | |
Notes
Diffstat (limited to 'sys/amd64/linux32')
| -rw-r--r-- | sys/amd64/linux32/linux32_sysvec.c | 64 |
1 files changed, 41 insertions, 23 deletions
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index 675834daeeab..ba87152d7a9a 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -103,7 +103,8 @@ SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler); static int linux_fixup_elf(register_t **stack_base, struct image_params *iparams); -static register_t *linux_copyout_strings(struct image_params *imgp); +static int linux_copyout_strings(struct image_params *imgp, + register_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); @@ -185,13 +186,13 @@ linux_translate_traps(int signal, int trap_code) } } -static void +static int linux_copyout_auxargs(struct image_params *imgp, u_long *base) { Elf32_Auxargs *args; Elf32_Auxinfo *argarray, *pos; u_long auxlen; - int issetugid; + int error, issetugid; args = (Elf32_Auxargs *)imgp->auxargs; argarray = pos = malloc(LINUX_AT_COUNT * sizeof(*pos), M_TEMP, @@ -239,8 +240,9 @@ linux_copyout_auxargs(struct image_params *imgp, u_long *base) auxlen = sizeof(*argarray) * (pos - argarray); *base -= auxlen; - copyout(argarray, (void *)*base, auxlen); + error = copyout(argarray, (void *)*base, auxlen); free(argarray, M_TEMP); + return (error); } static int @@ -718,13 +720,12 @@ linux_exec_setregs(struct thread *td, struct image_params *imgp, u_long stack) /* * XXX copied from ia32_sysvec.c. */ -static register_t * -linux_copyout_strings(struct image_params *imgp) +static int +linux_copyout_strings(struct image_params *imgp, register_t **stack_base) { - int argc, envc; + int argc, envc, error; u_int32_t *vectp; char *stringp, *destp; - u_int32_t *stack_base; struct linux32_ps_strings *arginfo; char canary[LINUX_AT_RANDOM_LEN]; size_t execpath_len; @@ -743,7 +744,10 @@ linux_copyout_strings(struct image_params *imgp) if (execpath_len != 0) { imgp->execpathp = (uintptr_t)arginfo - execpath_len; - copyout(imgp->execpath, (void *)imgp->execpathp, execpath_len); + error = copyout(imgp->execpath, (void *)imgp->execpathp, + execpath_len); + if (error != 0) + return (error); } /* Prepare the canary for SSP. */ @@ -751,11 +755,17 @@ linux_copyout_strings(struct image_params *imgp) imgp->canary = (uintptr_t)arginfo - roundup(execpath_len, sizeof(char *)) - roundup(sizeof(canary), sizeof(char *)); - copyout(canary, (void *)imgp->canary, sizeof(canary)); + error = copyout(canary, (void *)imgp->canary, sizeof(canary)); + if (error != 0) + return (error); vectp = (uint32_t *)destp; - if (imgp->auxargs) - imgp->sysent->sv_copyout_auxargs(imgp, (u_long *)&vectp); + if (imgp->auxargs) { + error = imgp->sysent->sv_copyout_auxargs(imgp, + (u_long *)&vectp); + if (error != 0) + return (error); + } /* * Allocate room for the argv[] and env vectors including the @@ -764,44 +774,52 @@ linux_copyout_strings(struct image_params *imgp) vectp -= imgp->args->argc + 1 + imgp->args->envc + 1; /* vectp also becomes our initial stack base. */ - stack_base = vectp; + *stack_base = (register_t *)vectp; stringp = imgp->args->begin_argv; argc = imgp->args->argc; envc = imgp->args->envc; /* Copy out strings - arguments and environment. */ - copyout(stringp, destp, ARG_MAX - imgp->args->stringspace); + error = copyout(stringp, destp, ARG_MAX - imgp->args->stringspace); + if (error != 0) + return (error); /* Fill in "ps_strings" struct for ps, w, etc. */ - suword32(&arginfo->ps_argvstr, (uint32_t)(intptr_t)vectp); - suword32(&arginfo->ps_nargvstr, argc); + if (suword32(&arginfo->ps_argvstr, (uint32_t)(intptr_t)vectp) != 0 || + suword32(&arginfo->ps_nargvstr, argc) != 0) + return (EFAULT); /* Fill in argument portion of vector table. */ for (; argc > 0; --argc) { - suword32(vectp++, (uint32_t)(intptr_t)destp); + if (suword32(vectp++, (uint32_t)(intptr_t)destp) != 0) + return (EFAULT); while (*stringp++ != 0) destp++; destp++; } /* A null vector table pointer separates the argp's from the envp's. */ - suword32(vectp++, 0); + if (suword32(vectp++, 0) != 0) + return (EFAULT); - suword32(&arginfo->ps_envstr, (uint32_t)(intptr_t)vectp); - suword32(&arginfo->ps_nenvstr, envc); + if (suword32(&arginfo->ps_envstr, (uint32_t)(intptr_t)vectp) != 0 || + suword32(&arginfo->ps_nenvstr, envc) != 0) + return (EFAULT); /* Fill in environment portion of vector table. */ for (; envc > 0; --envc) { - suword32(vectp++, (uint32_t)(intptr_t)destp); + if (suword32(vectp++, (uint32_t)(intptr_t)destp) != 0) + return (EFAULT); while (*stringp++ != 0) destp++; destp++; } /* The end of the vector table is a null pointer. */ - suword32(vectp, 0); + if (suword32(vectp, 0) != 0) + return (EFAULT); - return ((register_t *)stack_base); + return (0); } static SYSCTL_NODE(_compat, OID_AUTO, linux32, CTLFLAG_RW, 0, |
