Date: Mon, 18 Nov 2019 20:07:43 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r354827 - in head/sys: amd64/linux amd64/linux32 arm64/linux compat/cloudabi32 compat/cloudabi64 compat/freebsd32 i386/linux kern sys Message-ID: <201911182007.xAIK7hZP003616@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Mon Nov 18 20:07:43 2019 New Revision: 354827 URL: https://svnweb.freebsd.org/changeset/base/354827 Log: Check for errors from copyout() and suword*() in sv_copyout_args/strings. Reviewed by: brooks, kib Tested on: amd64 (amd64, i386, linux64), i386 (i386, linux) Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D22401 Modified: head/sys/amd64/linux/linux_sysvec.c head/sys/amd64/linux32/linux32_sysvec.c head/sys/arm64/linux/linux_sysvec.c head/sys/compat/cloudabi32/cloudabi32_module.c head/sys/compat/cloudabi32/cloudabi32_util.h head/sys/compat/cloudabi64/cloudabi64_module.c head/sys/compat/cloudabi64/cloudabi64_util.h head/sys/compat/freebsd32/freebsd32_misc.c head/sys/compat/freebsd32/freebsd32_util.h head/sys/i386/linux/linux_sysvec.c head/sys/kern/imgact_elf.c head/sys/kern/kern_exec.c head/sys/sys/imgact.h head/sys/sys/imgact_elf.h head/sys/sys/sysent.h Modified: head/sys/amd64/linux/linux_sysvec.c ============================================================================== --- head/sys/amd64/linux/linux_sysvec.c Mon Nov 18 20:03:28 2019 (r354826) +++ head/sys/amd64/linux/linux_sysvec.c Mon Nov 18 20:07:43 2019 (r354827) @@ -96,7 +96,8 @@ extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler); -static register_t * linux_copyout_strings(struct image_params *imgp); +static int linux_copyout_strings(struct image_params *imgp, + register_t **stack_base); static int linux_fixup_elf(register_t **stack_base, struct image_params *iparams); static bool linux_trans_osrel(const Elf_Note *note, int32_t *osrel); @@ -222,14 +223,14 @@ linux_set_syscall_retval(struct thread *td, int error) set_pcb_flags(td->td_pcb, PCB_FULL_IRET); } -static void +static int linux_copyout_auxargs(struct image_params *imgp, u_long *base) { Elf_Auxargs *args; Elf_Auxinfo *argarray, *pos; u_long auxlen; struct proc *p; - int issetugid; + int error, issetugid; p = imgp->proc; args = (Elf64_Auxargs *)imgp->auxargs; @@ -267,8 +268,9 @@ linux_copyout_auxargs(struct image_params *imgp, u_lon 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 @@ -290,13 +292,12 @@ linux_fixup_elf(register_t **stack_base, struct image_ * and env vector tables. Return a pointer to the base so that it can be used * as the initial stack pointer. */ -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; char **vectp; char *stringp, *destp; - register_t *stack_base; struct ps_strings *arginfo; char canary[LINUX_AT_RANDOM_LEN]; size_t execpath_len; @@ -317,7 +318,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. */ @@ -325,7 +329,9 @@ 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 = (char **)destp; @@ -335,8 +341,12 @@ linux_copyout_strings(struct image_params *imgp) */ vectp = (char **)((((uintptr_t)vectp + 8) & ~0xF) - 8); - 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 @@ -345,44 +355,53 @@ 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 = (register_t *)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. */ - suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp); - suword(&arginfo->ps_nargvstr, argc); + if (suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp) != 0 || + suword(&arginfo->ps_nargvstr, argc) != 0) + return (EFAULT); /* Fill in argument portion of vector table. */ for (; argc > 0; --argc) { - suword(vectp++, (long)(intptr_t)destp); + if (suword(vectp++, (long)(intptr_t)destp) != 0) + return (EFAULT); while (*stringp++ != 0) destp++; destp++; } /* A null vector table pointer separates the argp's from the envp's. */ - suword(vectp++, 0); + if (suword(vectp++, 0) != 0) + return (EFAULT); - suword(&arginfo->ps_envstr, (long)(intptr_t)vectp); - suword(&arginfo->ps_nenvstr, envc); + if (suword(&arginfo->ps_envstr, (long)(intptr_t)vectp) != 0 || + suword(&arginfo->ps_nenvstr, envc) != 0) + return (EFAULT); /* Fill in environment portion of vector table. */ for (; envc > 0; --envc) { - suword(vectp++, (long)(intptr_t)destp); + if (suword(vectp++, (long)(intptr_t)destp) != 0) + return (EFAULT); while (*stringp++ != 0) destp++; destp++; } /* The end of the vector table is a null pointer. */ - suword(vectp, 0); - return (stack_base); + if (suword(vectp, 0) != 0) + return (EFAULT); + + return (0); } /* Modified: head/sys/amd64/linux32/linux32_sysvec.c ============================================================================== --- head/sys/amd64/linux32/linux32_sysvec.c Mon Nov 18 20:03:28 2019 (r354826) +++ head/sys/amd64/linux32/linux32_sysvec.c Mon Nov 18 20:07:43 2019 (r354827) @@ -103,7 +103,8 @@ SET_DECLARE(linux_ioctl_handler_set, struct linux_ioct 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_lon 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_par /* * 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, Modified: head/sys/arm64/linux/linux_sysvec.c ============================================================================== --- head/sys/arm64/linux/linux_sysvec.c Mon Nov 18 20:03:28 2019 (r354826) +++ head/sys/arm64/linux/linux_sysvec.c Mon Nov 18 20:07:43 2019 (r354827) @@ -69,7 +69,8 @@ extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler); -static register_t *linux_copyout_strings(struct image_params *imgp); +static int linux_copyout_strings(struct image_params *imgp, + register_t **stack_base); static int linux_elf_fixup(register_t **stack_base, struct image_params *iparams); static bool linux_trans_osrel(const Elf_Note *note, int32_t *osrel); @@ -141,14 +142,14 @@ linux_set_syscall_retval(struct thread *td, int error) cpu_set_syscall_retval(td, error); } -static void +static int linux_copyout_auxargs(struct image_params *imgp, u_long *base) { Elf_Auxargs *args; Elf_Auxinfo *argarray, *pos; u_long auxlen; struct proc *p; - int issetugid; + int error, issetugid; LIN_SDT_PROBE0(sysvec, linux_copyout_auxargs, todo); p = imgp->proc; @@ -191,8 +192,9 @@ linux_copyout_auxargs(struct image_params *imgp, u_lon 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 @@ -210,17 +212,16 @@ linux_elf_fixup(register_t **stack_base, struct image_ * as the initial stack pointer. * LINUXTODO: deduplicate against other linuxulator archs */ -static register_t * -linux_copyout_strings(struct image_params *imgp) +static int +linux_copyout_strings(struct image_params *imgp, register_t **stack_base) { char **vectp; char *stringp, *destp; - register_t *stack_base; struct ps_strings *arginfo; char canary[LINUX_AT_RANDOM_LEN]; size_t execpath_len; struct proc *p; - int argc, envc; + int argc, envc, error; /* Calculate string base and vector table pointers. */ if (imgp->execpath != NULL && imgp->auxargs != NULL) @@ -237,7 +238,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. */ @@ -245,11 +249,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 = (char **)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 argc and the argv[] and env vectors including the @@ -259,45 +269,56 @@ linux_copyout_strings(struct image_params *imgp) vectp = (char **)STACKALIGN(vectp); /* vectp also becomes our initial stack base. */ - stack_base = (register_t *)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. */ - suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp); - suword(&arginfo->ps_nargvstr, argc); + if (suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp) != 0 || + suword(&arginfo->ps_nargvstr, argc) != 0) + return (EFAULT); - suword(vectp++, argc); + if (suword(vectp++, argc) != 0) + return (EFAULT); + /* Fill in argument portion of vector table. */ for (; argc > 0; --argc) { - suword(vectp++, (long)(intptr_t)destp); + if (suword(vectp++, (long)(intptr_t)destp) != 0) + return (EFAULT); while (*stringp++ != 0) destp++; destp++; } /* A null vector table pointer separates the argp's from the envp's. */ - suword(vectp++, 0); + if (suword(vectp++, 0) != 0) + return (EFAULT); - suword(&arginfo->ps_envstr, (long)(intptr_t)vectp); - suword(&arginfo->ps_nenvstr, envc); + if (suword(&arginfo->ps_envstr, (long)(intptr_t)vectp) != 0 || + suword(&arginfo->ps_nenvstr, envc) != 0) + return (EFAULT); /* Fill in environment portion of vector table. */ for (; envc > 0; --envc) { - suword(vectp++, (long)(intptr_t)destp); + if (suword(vectp++, (long)(intptr_t)destp) != 0) + return (EFAULT); while (*stringp++ != 0) destp++; destp++; } /* The end of the vector table is a null pointer. */ - suword(vectp, 0); - return (stack_base); + if (suword(vectp, 0) != 0) + return (EFAULT); + + return (0); } /* Modified: head/sys/compat/cloudabi32/cloudabi32_module.c ============================================================================== --- head/sys/compat/cloudabi32/cloudabi32_module.c Mon Nov 18 20:03:28 2019 (r354826) +++ head/sys/compat/cloudabi32/cloudabi32_module.c Mon Nov 18 20:07:43 2019 (r354827) @@ -45,8 +45,8 @@ __FBSDID("$FreeBSD$"); extern char _binary_cloudabi32_vdso_o_start[]; extern char _binary_cloudabi32_vdso_o_end[]; -register_t * -cloudabi32_copyout_strings(struct image_params *imgp) +int +cloudabi32_copyout_strings(struct image_params *imgp, register_t **stack_base) { struct image_args *args; uintptr_t begin; @@ -56,8 +56,8 @@ cloudabi32_copyout_strings(struct image_params *imgp) args = imgp->args; len = exec_args_get_begin_envv(args) - args->begin_argv; begin = rounddown2(imgp->sysent->sv_usrstack - len, sizeof(register_t)); - copyout(args->begin_argv, (void *)begin, len); - return ((register_t *)begin); + *stack_base = (register_t *)begin; + return (copyout(args->begin_argv, (void *)begin, len)); } int Modified: head/sys/compat/cloudabi32/cloudabi32_util.h ============================================================================== --- head/sys/compat/cloudabi32/cloudabi32_util.h Mon Nov 18 20:03:28 2019 (r354826) +++ head/sys/compat/cloudabi32/cloudabi32_util.h Mon Nov 18 20:07:43 2019 (r354827) @@ -42,7 +42,7 @@ extern Elf32_Brandinfo cloudabi32_brand; #define TO_PTR(x) ((void *)(uintptr_t)(x)) /* Stack initialization during process execution. */ -register_t *cloudabi32_copyout_strings(struct image_params *); +int cloudabi32_copyout_strings(struct image_params *, register_t **); int cloudabi32_fixup(register_t **, struct image_params *); int cloudabi32_thread_setregs(struct thread *, Modified: head/sys/compat/cloudabi64/cloudabi64_module.c ============================================================================== --- head/sys/compat/cloudabi64/cloudabi64_module.c Mon Nov 18 20:03:28 2019 (r354826) +++ head/sys/compat/cloudabi64/cloudabi64_module.c Mon Nov 18 20:07:43 2019 (r354827) @@ -45,8 +45,8 @@ __FBSDID("$FreeBSD$"); extern char _binary_cloudabi64_vdso_o_start[]; extern char _binary_cloudabi64_vdso_o_end[]; -register_t * -cloudabi64_copyout_strings(struct image_params *imgp) +int +cloudabi64_copyout_strings(struct image_params *imgp, register_t **stack_base) { struct image_args *args; uintptr_t begin; @@ -56,8 +56,8 @@ cloudabi64_copyout_strings(struct image_params *imgp) args = imgp->args; len = exec_args_get_begin_envv(args) - args->begin_argv; begin = rounddown2(imgp->sysent->sv_usrstack - len, sizeof(register_t)); - copyout(args->begin_argv, (void *)begin, len); - return ((register_t *)begin); + *stack_base = (register_t *)begin; + return (copyout(args->begin_argv, (void *)begin, len)); } int Modified: head/sys/compat/cloudabi64/cloudabi64_util.h ============================================================================== --- head/sys/compat/cloudabi64/cloudabi64_util.h Mon Nov 18 20:03:28 2019 (r354826) +++ head/sys/compat/cloudabi64/cloudabi64_util.h Mon Nov 18 20:07:43 2019 (r354827) @@ -42,7 +42,7 @@ extern Elf64_Brandinfo cloudabi64_brand; #define TO_PTR(x) ((void *)(uintptr_t)(x)) /* Stack initialization during process execution. */ -register_t *cloudabi64_copyout_strings(struct image_params *); +int cloudabi64_copyout_strings(struct image_params *, register_t **); int cloudabi64_fixup(register_t **, struct image_params *); int cloudabi64_thread_setregs(struct thread *, Modified: head/sys/compat/freebsd32/freebsd32_misc.c ============================================================================== --- head/sys/compat/freebsd32/freebsd32_misc.c Mon Nov 18 20:03:28 2019 (r354826) +++ head/sys/compat/freebsd32/freebsd32_misc.c Mon Nov 18 20:07:43 2019 (r354827) @@ -3119,19 +3119,18 @@ syscall32_helper_unregister(struct syscall_helper_data return (kern_syscall_helper_unregister(freebsd32_sysent, sd)); } -register_t * -freebsd32_copyout_strings(struct image_params *imgp) +int +freebsd32_copyout_strings(struct image_params *imgp, register_t **stack_base) { int argc, envc, i; u_int32_t *vectp; char *stringp; uintptr_t destp; - u_int32_t *stack_base; struct freebsd32_ps_strings *arginfo; char canary[sizeof(long) * 8]; int32_t pagesizes32[MAXPAGESIZES]; size_t execpath_len; - int szsigcode; + int error, szsigcode; /* * Calculate string base and vector table pointers. @@ -3155,8 +3154,10 @@ freebsd32_copyout_strings(struct image_params *imgp) if (szsigcode != 0) { destp -= szsigcode; destp = rounddown2(destp, sizeof(uint32_t)); - copyout(imgp->proc->p_sysent->sv_sigcode, (void *)destp, + error = copyout(imgp->proc->p_sysent->sv_sigcode, (void *)destp, szsigcode); + if (error != 0) + return (error); } /* @@ -3165,7 +3166,9 @@ freebsd32_copyout_strings(struct image_params *imgp) if (execpath_len != 0) { destp -= execpath_len; imgp->execpathp = destp; - copyout(imgp->execpath, (void *)destp, execpath_len); + error = copyout(imgp->execpath, (void *)destp, execpath_len); + if (error != 0) + return (error); } /* @@ -3174,7 +3177,9 @@ freebsd32_copyout_strings(struct image_params *imgp) arc4rand(canary, sizeof(canary), 0); destp -= sizeof(canary); imgp->canary = destp; - copyout(canary, (void *)destp, sizeof(canary)); + error = copyout(canary, (void *)destp, sizeof(canary)); + if (error != 0) + return (error); imgp->canarylen = sizeof(canary); /* @@ -3185,7 +3190,9 @@ freebsd32_copyout_strings(struct image_params *imgp) destp -= sizeof(pagesizes32); destp = rounddown2(destp, sizeof(uint32_t)); imgp->pagesizes = destp; - copyout(pagesizes32, (void *)destp, sizeof(pagesizes32)); + error = copyout(pagesizes32, (void *)destp, sizeof(pagesizes32)); + if (error != 0) + return (error); imgp->pagesizeslen = sizeof(pagesizes32); destp -= ARG_MAX - imgp->args->stringspace; @@ -3195,8 +3202,12 @@ freebsd32_copyout_strings(struct image_params *imgp) if (imgp->sysent->sv_stackgap != NULL) imgp->sysent->sv_stackgap(imgp, (u_long *)&vectp); - 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 @@ -3207,7 +3218,7 @@ freebsd32_copyout_strings(struct image_params *imgp) /* * vectp also becomes our initial stack base */ - stack_base = vectp; + *stack_base = (register_t *)vectp; stringp = imgp->args->begin_argv; argc = imgp->args->argc; @@ -3215,44 +3226,53 @@ freebsd32_copyout_strings(struct image_params *imgp) /* * Copy out strings - arguments and environment. */ - copyout(stringp, (void *)destp, ARG_MAX - imgp->args->stringspace); + error = copyout(stringp, (void *)destp, + ARG_MAX - imgp->args->stringspace); + if (error != 0) + return (error); /* * Fill in "ps_strings" struct for ps, w, etc. */ - suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); - suword32(&arginfo->ps_nargvstr, argc); + if (suword32(&arginfo->ps_argvstr, (u_int32_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++, (u_int32_t)(intptr_t)destp); + if (suword32(vectp++, (u_int32_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, (u_int32_t)(intptr_t)vectp); - suword32(&arginfo->ps_nenvstr, envc); + if (suword32(&arginfo->ps_envstr, (u_int32_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++, (u_int32_t)(intptr_t)destp); + if (suword32(vectp++, (u_int32_t)(intptr_t)destp) != 0) + return (EFAULT); while (*stringp++ != 0) destp++; destp++; } /* end of vector table is a null pointer */ - suword32(vectp, 0); + if (suword32(vectp, 0) != 0) + return (EFAULT); - return ((register_t *)stack_base); + return (0); } int Modified: head/sys/compat/freebsd32/freebsd32_util.h ============================================================================== --- head/sys/compat/freebsd32/freebsd32_util.h Mon Nov 18 20:03:28 2019 (r354826) +++ head/sys/compat/freebsd32/freebsd32_util.h Mon Nov 18 20:07:43 2019 (r354827) @@ -112,7 +112,8 @@ int syscall32_helper_unregister(struct syscall_help struct iovec32; struct rusage32; -register_t *freebsd32_copyout_strings(struct image_params *imgp); +int freebsd32_copyout_strings(struct image_params *imgp, + register_t **stack_base); int freebsd32_copyiniov(struct iovec32 *iovp, u_int iovcnt, struct iovec **iov, int error); void freebsd32_rusage_out(const struct rusage *s, struct rusage32 *s32); Modified: head/sys/i386/linux/linux_sysvec.c ============================================================================== --- head/sys/i386/linux/linux_sysvec.c Mon Nov 18 20:03:28 2019 (r354826) +++ head/sys/i386/linux/linux_sysvec.c Mon Nov 18 20:07:43 2019 (r354827) @@ -95,7 +95,8 @@ static int linux_fixup_elf(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); -static register_t *linux_copyout_strings(struct image_params *imgp); +static int linux_copyout_strings(struct image_params *imgp, + register_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); @@ -188,7 +189,7 @@ linux_fixup(register_t **stack_base, struct image_para return (0); } -static void +static int linux_copyout_auxargs(struct image_params *imgp, u_long *base) { struct proc *p; @@ -197,7 +198,7 @@ linux_copyout_auxargs(struct image_params *imgp, u_lon Elf32_Addr *uplatform; struct ps_strings *arginfo; u_long auxlen; - int issetugid; + int error, issetugid; p = imgp->proc; issetugid = imgp->proc->p_flag & P_SUGID ? 1 : 0; @@ -248,8 +249,9 @@ linux_copyout_auxargs(struct image_params *imgp, u_lon 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 @@ -265,13 +267,12 @@ linux_fixup_elf(register_t **stack_base, struct image_ /* * Copied from kern/kern_exec.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; char **vectp; char *stringp, *destp; - register_t *stack_base; struct ps_strings *arginfo; char canary[LINUX_AT_RANDOM_LEN]; size_t execpath_len; @@ -290,13 +291,18 @@ linux_copyout_strings(struct image_params *imgp) roundup(ARG_MAX - imgp->args->stringspace, sizeof(char *)); /* Install LINUX_PLATFORM. */ - copyout(linux_kplatform, ((caddr_t)arginfo - linux_szplatform), + error = copyout(linux_kplatform, ((caddr_t)arginfo - linux_szplatform), linux_szplatform); + if (error != 0) + return (error); if (execpath_len != 0) { imgp->execpathp = (uintptr_t)arginfo - linux_szplatform - 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. */ @@ -304,11 +310,17 @@ linux_copyout_strings(struct image_params *imgp) imgp->canary = (uintptr_t)arginfo - linux_szplatform - 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 = (char **)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 @@ -317,45 +329,53 @@ 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 = (register_t *)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. */ - suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp); - suword(&arginfo->ps_nargvstr, argc); + if (suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp) != 0 || + suword(&arginfo->ps_nargvstr, argc) != 0) + return (EFAULT); /* Fill in argument portion of vector table. */ for (; argc > 0; --argc) { - suword(vectp++, (long)(intptr_t)destp); + if (suword(vectp++, (long)(intptr_t)destp) != 0) + return (EFAULT); while (*stringp++ != 0) destp++; destp++; } /* A null vector table pointer separates the argp's from the envp's. */ - suword(vectp++, 0); + if (suword(vectp++, 0) != 0) + return (EFAULT); - suword(&arginfo->ps_envstr, (long)(intptr_t)vectp); - suword(&arginfo->ps_nenvstr, envc); + if (suword(&arginfo->ps_envstr, (long)(intptr_t)vectp) != 0 || + suword(&arginfo->ps_nenvstr, envc) != 0) + return (EFAULT); /* Fill in environment portion of vector table. */ for (; envc > 0; --envc) { - suword(vectp++, (long)(intptr_t)destp); + if (suword(vectp++, (long)(intptr_t)destp) != 0) + return (EFAULT); while (*stringp++ != 0) destp++; destp++; } /* The end of the vector table is a null pointer. */ - suword(vectp, 0); + if (suword(vectp, 0) != 0) + return (EFAULT); - return (stack_base); + return (0); } static void Modified: head/sys/kern/imgact_elf.c ============================================================================== --- head/sys/kern/imgact_elf.c Mon Nov 18 20:03:28 2019 (r354826) +++ head/sys/kern/imgact_elf.c Mon Nov 18 20:07:43 2019 (r354827) @@ -1323,12 +1323,13 @@ ret: #define suword __CONCAT(suword, __ELF_WORD_SIZE) -void +int __elfN(freebsd_copyout_auxargs)(struct image_params *imgp, u_long *base) { Elf_Auxargs *args = (Elf_Auxargs *)imgp->auxargs; Elf_Auxinfo *argarray, *pos; u_long auxlen; + int error; argarray = pos = malloc(AT_COUNT * sizeof(*pos), M_TEMP, M_WAITOK | M_ZERO); @@ -1375,8 +1376,9 @@ __elfN(freebsd_copyout_auxargs)(struct image_params *i auxlen = sizeof(*argarray) * (pos - argarray); *base -= auxlen; - copyout(argarray, (void *)*base, auxlen); + error = copyout(argarray, (void *)*base, auxlen); free(argarray, M_TEMP); + return (error); } int Modified: head/sys/kern/kern_exec.c ============================================================================== --- head/sys/kern/kern_exec.c Mon Nov 18 20:03:28 2019 (r354826) +++ head/sys/kern/kern_exec.c Mon Nov 18 20:07:43 2019 (r354827) @@ -672,7 +672,11 @@ interpret: /* * Copy out strings (args and env) and initialize stack base. */ - stack_base = (*p->p_sysent->sv_copyout_strings)(imgp); + error = (*p->p_sysent->sv_copyout_strings)(imgp, &stack_base); + if (error != 0) { + vn_lock(imgp->vp, LK_SHARED | LK_RETRY); + goto exec_fail_dealloc; + } /* * Stack setup. @@ -1569,18 +1573,17 @@ exec_args_get_begin_envv(struct image_args *args) * and env vector tables. Return a pointer to the base so that it can be used * as the initial stack pointer. */ -register_t * -exec_copyout_strings(struct image_params *imgp) +int +exec_copyout_strings(struct image_params *imgp, register_t **stack_base) { int argc, envc; char **vectp; char *stringp; uintptr_t destp; - register_t *stack_base; struct ps_strings *arginfo; struct proc *p; size_t execpath_len; - int szsigcode, szps; + int error, szsigcode, szps; char canary[sizeof(long) * 8]; szps = sizeof(pagesizes[0]) * MAXPAGESIZES; @@ -1607,7 +1610,10 @@ exec_copyout_strings(struct image_params *imgp) if (szsigcode != 0) { destp -= szsigcode; destp = rounddown2(destp, sizeof(void *)); - copyout(p->p_sysent->sv_sigcode, (void *)destp, szsigcode); + error = copyout(p->p_sysent->sv_sigcode, (void *)destp, + szsigcode); + if (error != 0) + return (error); } /* @@ -1617,7 +1623,9 @@ exec_copyout_strings(struct image_params *imgp) destp -= execpath_len; destp = rounddown2(destp, sizeof(void *)); imgp->execpathp = destp; - copyout(imgp->execpath, (void *)destp, execpath_len); + error = copyout(imgp->execpath, (void *)destp, execpath_len); + if (error != 0) + return (error); } /* @@ -1626,7 +1634,9 @@ exec_copyout_strings(struct image_params *imgp) arc4rand(canary, sizeof(canary), 0); destp -= sizeof(canary); imgp->canary = destp; - copyout(canary, (void *)destp, sizeof(canary)); + error = copyout(canary, (void *)destp, sizeof(canary)); + if (error != 0) + return (error); imgp->canarylen = sizeof(canary); /* @@ -1635,7 +1645,9 @@ exec_copyout_strings(struct image_params *imgp) destp -= szps; destp = rounddown2(destp, sizeof(void *)); imgp->pagesizes = destp; - copyout(pagesizes, (void *)destp, szps); + error = copyout(pagesizes, (void *)destp, szps); + if (error != 0) + return (error); imgp->pagesizeslen = szps; destp -= ARG_MAX - imgp->args->stringspace; @@ -1645,8 +1657,12 @@ exec_copyout_strings(struct image_params *imgp) if (imgp->sysent->sv_stackgap != NULL) imgp->sysent->sv_stackgap(imgp, (u_long *)&vectp); - 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); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911182007.xAIK7hZP003616>