diff options
| author | Kyle Evans <kevans@FreeBSD.org> | 2020-06-10 01:30:37 +0000 |
|---|---|---|
| committer | Kyle Evans <kevans@FreeBSD.org> | 2020-06-10 01:30:37 +0000 |
| commit | 301cb491ea417e54c29e63ebe00afbc8de47cd1f (patch) | |
| tree | f537b25e28fe530e189543e98c350281e78db50a /lib/libc/gen | |
| parent | 1138b87ae640bb1ac22549ddb0490ebed692070c (diff) | |
Notes
Diffstat (limited to 'lib/libc/gen')
| -rw-r--r-- | lib/libc/gen/exec.c | 22 |
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; |
