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 ***
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to