Skip site navigation (1)Skip section navigation (2)
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>