mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-27 02:48:48 +00:00
avoid assimilating
This commit is contained in:
parent
2df75e902b
commit
64275e9cd7
1 changed files with 87 additions and 36 deletions
|
@ -21,6 +21,7 @@
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/cp.internal.h"
|
#include "libc/calls/cp.internal.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/state.internal.h"
|
||||||
#include "libc/calls/struct/sigset.internal.h"
|
#include "libc/calls/struct/sigset.internal.h"
|
||||||
#include "libc/calls/struct/stat.internal.h"
|
#include "libc/calls/struct/stat.internal.h"
|
||||||
#include "libc/calls/syscall-sysv.internal.h"
|
#include "libc/calls/syscall-sysv.internal.h"
|
||||||
|
@ -199,9 +200,9 @@ static int fd_to_mem_fd(const int infd, char *path) {
|
||||||
bool success = readRc != -1;
|
bool success = readRc != -1;
|
||||||
if (success) {
|
if (success) {
|
||||||
int ziperror;
|
int ziperror;
|
||||||
if ((st.st_size > 8) && IsApeMagic(space)) {
|
//if ((st.st_size > 8) && IsApeMagic(space)) {
|
||||||
success = ape_to_elf(space, st.st_size);
|
// success = ape_to_elf(space, st.st_size);
|
||||||
}
|
//}
|
||||||
// we need to preserve the fd over exec if there's zipos
|
// we need to preserve the fd over exec if there's zipos
|
||||||
if (success && _weaken(GetZipEocd) && _weaken(GetZipEocd)(space, st.st_size, &ziperror)) {
|
if (success && _weaken(GetZipEocd) && _weaken(GetZipEocd)(space, st.st_size, &ziperror)) {
|
||||||
int flags = fcntl(fd, F_GETFD);
|
int flags = fcntl(fd, F_GETFD);
|
||||||
|
@ -232,6 +233,30 @@ static int fd_to_mem_fd(const int infd, char *path) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int isZipFd(const int fd) {
|
||||||
|
if (!_weaken(mmap) || !_weaken(munmap) || !_weaken(GetZipEocd)) {
|
||||||
|
return enosys();
|
||||||
|
}
|
||||||
|
if (__vforked) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
struct stat st;
|
||||||
|
if (fstat(fd, &st) == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
void *space = _weaken(mmap)(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
|
if (space == MAP_FAILED) {
|
||||||
|
STRACE("map failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int ziperror;
|
||||||
|
int rc = _weaken(GetZipEocd)(space, st.st_size, &ziperror) != NULL;
|
||||||
|
if(_weaken(munmap)(space, st.st_size) == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes binary executable at file descriptor.
|
* Executes binary executable at file descriptor.
|
||||||
*
|
*
|
||||||
|
@ -260,55 +285,81 @@ int fexecve(int fd, char *const argv[], char *const envp[]) {
|
||||||
rc = enosys();
|
rc = enosys();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!__isfdkind(fd, kFdZip)) {
|
int newfd = fd;
|
||||||
bool memfdReq;
|
if (__isfdkind(fd, kFdZip)) {
|
||||||
BLOCK_SIGNALS;
|
BLOCK_SIGNALS;
|
||||||
BLOCK_CANCELATION;
|
BLOCK_CANCELATION;
|
||||||
strace_enabled(-1);
|
strace_enabled(-1);
|
||||||
memfdReq = ((rc = fcntl(fd, F_GETFD)) != -1) && (rc & FD_CLOEXEC) &&
|
newfd = fd_to_mem_fd(fd, NULL);
|
||||||
IsAPEFd(fd);
|
|
||||||
strace_enabled(+1);
|
strace_enabled(+1);
|
||||||
ALLOW_CANCELATION;
|
ALLOW_CANCELATION;
|
||||||
ALLOW_SIGNALS;
|
ALLOW_SIGNALS;
|
||||||
if (rc == -1) {
|
if (newfd == -1) {
|
||||||
break;
|
break;
|
||||||
} else if (!memfdReq) {
|
|
||||||
fexecve_impl(fd, argv, envp);
|
|
||||||
if (errno != ENOEXEC) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
savedErr = ENOEXEC;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int newfd;
|
int isZipFdRc;
|
||||||
char *path = alloca(PATH_MAX);
|
|
||||||
BLOCK_SIGNALS;
|
BLOCK_SIGNALS;
|
||||||
BLOCK_CANCELATION;
|
BLOCK_CANCELATION;
|
||||||
strace_enabled(-1);
|
//strace_enabled(-1);
|
||||||
newfd = fd_to_mem_fd(fd, path);
|
isZipFdRc = isZipFd(newfd);
|
||||||
strace_enabled(+1);
|
strace_enabled(+1);
|
||||||
ALLOW_CANCELATION;
|
ALLOW_CANCELATION;
|
||||||
ALLOW_SIGNALS;
|
ALLOW_SIGNALS;
|
||||||
if (newfd == -1) {
|
if (isZipFdRc == -1) {
|
||||||
|
//savedErr = EACCES;
|
||||||
|
//STRACE("EACCESS 1");
|
||||||
|
//break;
|
||||||
|
isZipFdRc = 0;
|
||||||
|
}
|
||||||
|
bool isAPE;
|
||||||
|
BLOCK_SIGNALS;
|
||||||
|
BLOCK_CANCELATION;
|
||||||
|
isAPE = IsAPEFd(newfd);
|
||||||
|
ALLOW_CANCELATION;
|
||||||
|
ALLOW_SIGNALS;
|
||||||
|
if ((isZipFdRc == 1) || isAPE) {
|
||||||
|
int flags = fcntl(newfd, F_GETFD);
|
||||||
|
if ((flags == -1) || (fcntl(newfd, F_SETFD, flags & (~FD_CLOEXEC)) == -1)) {
|
||||||
|
savedErr = EACCES;
|
||||||
|
STRACE("EACCESS 2");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const int highfd = fcntl(newfd, F_DUPFD, 9001);
|
||||||
|
if (highfd != -1) {
|
||||||
|
close(newfd);
|
||||||
|
newfd = highfd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isZipFdRc == 1) {
|
||||||
|
char *path = alloca(PATH_MAX);
|
||||||
|
FormatInt32(stpcpy(path, "COSMOPOLITAN_INIT_ZIPOS="), newfd);
|
||||||
|
size_t numenvs;
|
||||||
|
for (numenvs = 0; envp[numenvs];) ++numenvs;
|
||||||
|
static _Thread_local char *envs[500];
|
||||||
|
memcpy(envs, envp, numenvs * sizeof(char *));
|
||||||
|
envs[numenvs] = path;
|
||||||
|
envs[numenvs + 1] = NULL;
|
||||||
|
envp = envs;
|
||||||
|
}
|
||||||
|
if (isAPE) {
|
||||||
|
char path[14 + 12];
|
||||||
|
FormatInt32(stpcpy(path, "/proc/self/fd/"), newfd);
|
||||||
|
rc = sys_execve(path, argv, envp);
|
||||||
|
savedErr = errno;
|
||||||
|
BLOCK_SIGNALS;
|
||||||
|
BLOCK_CANCELATION;
|
||||||
|
strace_enabled(-1);
|
||||||
|
if (newfd != fd) {
|
||||||
|
close(newfd);
|
||||||
|
}
|
||||||
|
strace_enabled(+1);
|
||||||
|
ALLOW_CANCELATION;
|
||||||
|
ALLOW_SIGNALS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
size_t numenvs;
|
fexecve_impl(newfd, argv, envp);
|
||||||
for (numenvs = 0; envp[numenvs];) ++numenvs;
|
savedErr = errno;
|
||||||
static _Thread_local char *envs[500];
|
|
||||||
memcpy(envs, envp, numenvs * sizeof(char *));
|
|
||||||
envs[numenvs] = path;
|
|
||||||
envs[numenvs + 1] = NULL;
|
|
||||||
fexecve_impl(newfd, argv, envs);
|
|
||||||
if (!savedErr) {
|
|
||||||
savedErr = errno;
|
|
||||||
}
|
|
||||||
BLOCK_SIGNALS;
|
|
||||||
BLOCK_CANCELATION;
|
|
||||||
strace_enabled(-1);
|
|
||||||
close(newfd);
|
|
||||||
strace_enabled(+1);
|
|
||||||
ALLOW_CANCELATION;
|
|
||||||
ALLOW_SIGNALS;
|
|
||||||
} while (0);
|
} while (0);
|
||||||
if (savedErr) {
|
if (savedErr) {
|
||||||
errno = savedErr;
|
errno = savedErr;
|
||||||
|
|
Loading…
Add table
Reference in a new issue