aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/gen
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2020-06-10 01:30:37 +0000
committerKyle Evans <kevans@FreeBSD.org>2020-06-10 01:30:37 +0000
commit301cb491ea417e54c29e63ebe00afbc8de47cd1f (patch)
treef537b25e28fe530e189543e98c350281e78db50a /lib/libc/gen
parent1138b87ae640bb1ac22549ddb0490ebed692070c (diff)
Notes
Diffstat (limited to 'lib/libc/gen')
-rw-r--r--lib/libc/gen/exec.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/lib/libc/gen/exec.c b/lib/libc/gen/exec.c
index 799a89d5c7e31..76c0454600eb2 100644
--- a/lib/libc/gen/exec.c
+++ b/lib/libc/gen/exec.c
@@ -215,14 +215,28 @@ retry: (void)_execve(bp, argv, envp);
case ENOEXEC:
for (cnt = 0; argv[cnt]; ++cnt)
;
- memp = alloca((cnt + 2) * sizeof(char *));
+
+ /*
+ * cnt may be 0 above; always allocate at least
+ * 3 entries so that we can at least fit "sh", bp, and
+ * the NULL terminator. We can rely on cnt to take into
+ * account the NULL terminator in all other scenarios,
+ * as we drop argv[0].
+ */
+ memp = alloca(MAX(3, cnt + 2) * sizeof(char *));
if (memp == NULL) {
/* errno = ENOMEM; XXX override ENOEXEC? */
goto done;
}
- memp[0] = "sh";
- memp[1] = bp;
- bcopy(argv + 1, memp + 2, cnt * sizeof(char *));
+ if (cnt > 0) {
+ memp[0] = argv[0];
+ memp[1] = bp;
+ bcopy(argv + 1, memp + 2, cnt * sizeof(char *));
+ } else {
+ memp[0] = "sh";
+ memp[1] = bp;
+ memp[2] = NULL;
+ }
(void)_execve(_PATH_BSHELL,
__DECONST(char **, memp), envp);
goto done;