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