summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/linux32/linux32_machdep.c23
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c22
-rw-r--r--sys/kern/kern_exec.c29
3 files changed, 46 insertions, 28 deletions
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
index 2163bc2..83ebf53 100644
--- a/sys/amd64/linux32/linux32_machdep.c
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -130,7 +130,7 @@ linux_exec_copyin_args(struct image_args *args, char *fname,
copystr(fname, args->fname, PATH_MAX, &length) :
copyinstr(fname, args->fname, PATH_MAX, &length);
if (error != 0)
- return (error);
+ goto err_exit;
/*
* extract arguments first
@@ -139,16 +139,16 @@ linux_exec_copyin_args(struct image_args *args, char *fname,
for (;;) {
error = copyin(p32++, &arg, sizeof(arg));
if (error)
- return (error);
+ goto err_exit;
if (arg == 0)
break;
argp = PTRIN(arg);
error = copyinstr(argp, args->endp, args->stringspace, &length);
if (error) {
if (error == ENAMETOOLONG)
- return (E2BIG);
- else
- return (error);
+ error = E2BIG;
+
+ goto err_exit;
}
args->stringspace -= length;
args->endp += length;
@@ -165,7 +165,7 @@ linux_exec_copyin_args(struct image_args *args, char *fname,
for (;;) {
error = copyin(p32++, &arg, sizeof(arg));
if (error)
- return (error);
+ goto err_exit;
if (arg == 0)
break;
envp = PTRIN(arg);
@@ -173,9 +173,8 @@ linux_exec_copyin_args(struct image_args *args, char *fname,
&length);
if (error) {
if (error == ENAMETOOLONG)
- return (E2BIG);
- else
- return (error);
+ error = E2BIG;
+ goto err_exit;
}
args->stringspace -= length;
args->endp += length;
@@ -184,6 +183,12 @@ linux_exec_copyin_args(struct image_args *args, char *fname,
}
return (0);
+
+err_exit:
+ kmem_free_wakeup(exec_map, (vm_offset_t)args->buf,
+ PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
+ args->buf = NULL;
+ return (error);
}
int
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 1045d12..472ef24 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -260,7 +260,7 @@ freebsd32_exec_copyin_args(struct image_args *args, char *fname,
copystr(fname, args->fname, PATH_MAX, &length) :
copyinstr(fname, args->fname, PATH_MAX, &length);
if (error != 0)
- return (error);
+ goto err_exit;
/*
* extract arguments first
@@ -269,16 +269,15 @@ freebsd32_exec_copyin_args(struct image_args *args, char *fname,
for (;;) {
error = copyin(p32++, &arg, sizeof(arg));
if (error)
- return (error);
+ goto err_exit;
if (arg == 0)
break;
argp = PTRIN(arg);
error = copyinstr(argp, args->endp, args->stringspace, &length);
if (error) {
if (error == ENAMETOOLONG)
- return (E2BIG);
- else
- return (error);
+ error = E2BIG;
+ goto err_exit;
}
args->stringspace -= length;
args->endp += length;
@@ -295,7 +294,7 @@ freebsd32_exec_copyin_args(struct image_args *args, char *fname,
for (;;) {
error = copyin(p32++, &arg, sizeof(arg));
if (error)
- return (error);
+ goto err_exit;
if (arg == 0)
break;
envp = PTRIN(arg);
@@ -303,9 +302,8 @@ freebsd32_exec_copyin_args(struct image_args *args, char *fname,
&length);
if (error) {
if (error == ENAMETOOLONG)
- return (E2BIG);
- else
- return (error);
+ error = E2BIG;
+ goto err_exit;
}
args->stringspace -= length;
args->endp += length;
@@ -314,6 +312,12 @@ freebsd32_exec_copyin_args(struct image_args *args, char *fname,
}
return (0);
+
+err_exit:
+ kmem_free_wakeup(exec_map, (vm_offset_t)args->buf,
+ PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
+ args->buf = NULL;
+ return (error);
}
int
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index c2392ff..acc64d2 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -243,6 +243,7 @@ kern_execve(td, args, mac_p)
PROC_LOCK(p);
if (thread_single(SINGLE_BOUNDARY)) {
PROC_UNLOCK(p);
+ exec_free_args(args);
return (ERESTART); /* Try again later. */
}
PROC_UNLOCK(p);
@@ -980,19 +981,21 @@ exec_copyin_args(struct image_args *args, char *fname,
copystr(fname, args->fname, PATH_MAX, &length) :
copyinstr(fname, args->fname, PATH_MAX, &length);
if (error != 0)
- return (error);
+ goto err_exit;
/*
* extract arguments first
*/
while ((argp = (caddr_t) (intptr_t) fuword(argv++))) {
- if (argp == (caddr_t) -1)
- return (EFAULT);
+ if (argp == (caddr_t) -1) {
+ error = EFAULT;
+ goto err_exit;
+ }
if ((error = copyinstr(argp, args->endp,
args->stringspace, &length))) {
- if (error == ENAMETOOLONG)
- return (E2BIG);
- return (error);
+ if (error == ENAMETOOLONG)
+ error = E2BIG;
+ goto err_exit;
}
args->stringspace -= length;
args->endp += length;
@@ -1006,13 +1009,15 @@ exec_copyin_args(struct image_args *args, char *fname,
*/
if (envv) {
while ((envp = (caddr_t)(intptr_t)fuword(envv++))) {
- if (envp == (caddr_t)-1)
- return (EFAULT);
+ if (envp == (caddr_t)-1) {
+ error = EFAULT;
+ goto err_exit;
+ }
if ((error = copyinstr(envp, args->endp,
args->stringspace, &length))) {
if (error == ENAMETOOLONG)
- return (E2BIG);
- return (error);
+ error = E2BIG;
+ goto err_exit;
}
args->stringspace -= length;
args->endp += length;
@@ -1021,6 +1026,10 @@ exec_copyin_args(struct image_args *args, char *fname,
}
return (0);
+
+err_exit:
+ exec_free_args(args);
+ return (error);
}
static void
OpenPOWER on IntegriCloud