APE fexecve, pass fd via envp to initialize zipos

This commit is contained in:
Gavin Hayes 2023-02-25 17:58:40 -05:00
parent 3647bf2094
commit b0be622915
2 changed files with 24 additions and 24 deletions

View file

@ -190,6 +190,7 @@ int fexecve(int fd, char *const argv[], char *const envp[]) {
} else { } else {
STRACE("fexecve(%d, %s, %s) → ...", fd, DescribeStringList(argv), STRACE("fexecve(%d, %s, %s) → ...", fd, DescribeStringList(argv),
DescribeStringList(envp)); DescribeStringList(envp));
int savedErr = 0;
do { do {
if (!IsLinux() && !IsFreebsd()) { if (!IsLinux() && !IsFreebsd()) {
rc = enosys(); rc = enosys();
@ -208,10 +209,11 @@ int fexecve(int fd, char *const argv[], char *const envp[]) {
if (rc == -1) { if (rc == -1) {
break; break;
} else if (!memfdReq) { } else if (!memfdReq) {
rc = fexecve_impl(fd, argv, envp); fexecve_impl(fd, argv, envp);
if (errno != ENOEXEC) { if (errno != ENOEXEC) {
break; break;
} }
savedErr = ENOEXEC;
} }
} }
int newfd; int newfd;
@ -224,27 +226,23 @@ int fexecve(int fd, char *const argv[], char *const envp[]) {
ALLOW_SIGNALS; ALLOW_SIGNALS;
END_CANCELLATION_POINT; END_CANCELLATION_POINT;
if (newfd == -1) { if (newfd == -1) {
if (rc == -1) {
errno = ENOEXEC;
}
rc = -1;
break; break;
} }
size_t numargs; size_t numenvs;
for (numargs = 0; argv[numargs];) ++numargs; for (numenvs = 0; envp[numenvs];) ++numenvs;
const size_t desargs = min(128, max(numargs + 1, 2)); const size_t desenvs = min(500, max(numenvs + 1, 2));
char **args = alloca(desargs * sizeof(char *)); char *envs[500];
args[0] = path; if (envs) {
if(numargs > 0) { memcpy(envs, envp, numenvs * sizeof(char *));
argv++; envs[numenvs] = path;
envs[numenvs+1] = NULL;
fexecve_impl(newfd, argv, envs);
if(!savedErr) {
savedErr = errno;
}
} else if(!savedErr) {
savedErr = ENOMEM;
} }
memcpy(args + 1, argv, (desargs - 1) * sizeof(char *));
fexecve_impl(newfd, args, envp);
if (rc == -1) {
errno = ENOEXEC;
}
rc = -1;
const int savedErr = errno;
BEGIN_CANCELLATION_POINT; BEGIN_CANCELLATION_POINT;
BLOCK_SIGNALS; BLOCK_SIGNALS;
strace_enabled(-1); strace_enabled(-1);
@ -252,8 +250,11 @@ int fexecve(int fd, char *const argv[], char *const envp[]) {
strace_enabled(+1); strace_enabled(+1);
ALLOW_SIGNALS; ALLOW_SIGNALS;
END_CANCELLATION_POINT; END_CANCELLATION_POINT;
errno = savedErr;
} while (0); } while (0);
if(savedErr) {
errno = savedErr;
}
rc = -1;
} }
STRACE("fexecve(%d) failed %d% m", fd, rc); STRACE("fexecve(%d) failed %d% m", fd, rc);
return rc; return rc;

View file

@ -68,10 +68,9 @@ struct Zipos *__zipos_get(void) {
const char *progpath; const char *progpath;
static struct Zipos zipos; static struct Zipos zipos;
uint8_t *map, *base, *cdir; uint8_t *map, *base, *cdir;
static const char fdProgName[] = "COSMOPOLITAN_INIT_ZIPOS="; progpath = getenv("COSMOPOLITAN_INIT_ZIPOS");
if(__argc && (strncmp(fdProgName, __argv[0], sizeof(fdProgName)-1) == 0)) { if(progpath) {
fd = atoi(__argv[0]+sizeof(fdProgName)-1); fd = atoi(progpath);
progpath = __argv[0];
} }
if (!once && ((fd != -1) || PLEDGED(RPATH))) { if (!once && ((fd != -1) || PLEDGED(RPATH))) {
__zipos_lock(); __zipos_lock();