[*] POSIX: AuProcesses mustn't allocate (sorta) while in a COW address space (including accessing bad CRT apis)

This commit is contained in:
Reece Wilson 2024-08-05 22:13:02 +01:00
parent 57c5515173
commit db233d363a
2 changed files with 94 additions and 36 deletions

View File

@ -437,16 +437,46 @@ namespace Aurora::Processes
InitProcessStdHandles(this->startup_.fwdErr, this->pipeStdErr_, AuIO::EStandardStream::eErrorStream, this->startup_.handleErrorStream);
InitProcessStdHandles(this->startup_.fwdIn, this->pipeStdIn_, AuIO::EStandardStream::eInputStream, this->startup_.handleInputStream);
this->loopSource_ = AuMakeShared<ProcessAliveLoopSource>();
if (!this->loopSource_)
if (!AuFS::FileExists(this->startup_.process))
{
SysPushErrorIO("No Process Module / Missing File");
return false;
}
this->loopSource_ = AuMakeShared<ProcessAliveLoopSource>();
if (!this->loopSource_)
{
SysPushErrorMemory();
return false;
}
this->pSemaphore_ = AuLoop::NewLSSemaphoreSlow(0);
if (!this->pSemaphore_)
{
SysPushErrorIO("No sync");
return false;
}
{
auto semaphoreFd = AuLoop::DbgLoopSourceToReadFd(this->pSemaphore_);
int iFlags = fcntl(semaphoreFd, F_GETFD, 0);
if (iFlags < 0)
{
SysPushErrorIO("fcntl error");
return false;
}
iFlags &= ~FD_CLOEXEC;
if (fcntl(semaphoreFd, F_SETFD, iFlags) < 0)
{
SysPushErrorIO("fcntl error");
return false;
}
}
this->finished_ = AuThreadPrimitives::EventShared(false, false, true);
if (!this->finished_)
{
SysPushErrorIO("No sync");
return false;
}
@ -561,6 +591,16 @@ namespace Aurora::Processes
{
PosixDoForkHooks();
static const auto kForkMemSize = 10 * 1024 * 1024;
auto pHeapMemory = SysAllocateLarge(kForkMemSize);
if (!pHeapMemory)
{
return;
}
AuMemoryViewWrite heapView { pHeapMemory, kForkMemSize };
AuMemory::RequestHeapOfRegion heapObject(heapView);
{
::dup2(this->pipeStdIn_[0], STDIN_FILENO);
::close(this->pipeStdIn_[0]);
@ -587,32 +627,6 @@ namespace Aurora::Processes
{
::setsid();
}
if (!this->startup_.bInheritEnvironmentVariables)
{
try
{
AuList<AuString> keys;
for (const auto &[key, value] : AuProcess::EnvironmentGetAll())
{
keys.push_back(key);
}
AuProcess::EnvironmentRemoveMany(keys);
}
catch (...)
{
SysPanic("Couldn't fork");
}
}
PosixFDYeetus();
if (this->startup_.environmentVariables.size())
{
SysAssert(AuProcess::EnvironmentSetMany(this->startup_.environmentVariables));
}
#if defined(AURORA_IS_XNU_DERIVED)
if (this->startup_.workingDirectory)
@ -659,7 +673,7 @@ namespace Aurora::Processes
#elif defined(AURORA_IS_POSIX_DERIVED)
if (auto cpuSet = cpuset_alloc())
if (auto cpuSet = heapObject->ZAlloc<cpuset_t *>(CPU_ALLOC_SIZE(512))) //cpuset_alloc())
{
cpuset_init(cpuSet);
@ -672,7 +686,7 @@ namespace Aurora::Processes
pthread_setaffinity_np(pthread_self(), cpuset_size(cpuSet), cpuSet);
cpuset_free(cpuSet);
//cpuset_free(cpuSet);
}
#else
@ -686,16 +700,57 @@ namespace Aurora::Processes
{
this->startup_.posixApplySandboxCOW();
}
::execv(this->startup_.process.c_str(), (char * const *)this->cargs_.data()); // https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
SysPushErrorGen("execv didn't overwrite the process map. Launch: {} ({})", this->startup_.process, this->debug_);
auto pProcessPath = heapObject->ZAlloc<char *>(this->startup_.process.size() + 1);
AuMemcpy(pProcessPath, this->startup_.process.c_str(), this->startup_.process.size());
auto pArgsBlock = heapObject->ZAlloc<void **>((this->cargs_.size() + 1) * sizeof(void *));
for (AU_ITERATE_N(i, this->cargs_.size()))
{
if (auto pString = this->cargs_[i])
{
auto uLength = strlen(pString) + 1;
auto pArg = heapObject->ZAlloc<char *>(uLength);
AuMemcpy(pArg, pString, uLength);
pArgsBlock[i] = pArg;
}
}
auto pEnvArgsBlock = heapObject->ZAlloc<void **>((this->startup_.environmentVariables.size() + 1) * sizeof(void *));
for (AU_ITERATE_N(i, this->startup_.environmentVariables.size()))
{
auto &[key, value] = this->startup_.environmentVariables[i];
auto uLength = key.size() + value.size() + 2;
auto pArg = heapObject->ZAlloc<char *>(uLength);
AuMemcpy(pArg, key.data(), key.size());
pArg[key.size()] = '=';
AuMemcpy(pArg + key.size() + 1, value.data(), value.size());
pEnvArgsBlock[i] = pArg;
}
{
auto semaphoreFd = AuLoop::DbgLoopSourceToReadFd(this->pSemaphore_);
this->pSemaphore_->AddOne();
close(semaphoreFd);
}
PosixFDYeetus();
::execve(pProcessPath, (char * const *)pArgsBlock, (char * const *)pEnvArgsBlock); // https://pubs.opengroup.org/onlinepubs/9699919799/functions/execve.html
}
bool ProcessImpl::Start()
{
this->exitCode_ = 0x10110100;
if (this->startup_.bInheritEnvironmentVariables)
{
for (const auto &[key, value] : AuProcess::EnvironmentGetAll())
{
this->startup_.environmentVariables.insert(this->startup_.environmentVariables.begin(), AuMakePair(key, value));
}
}
if (this->type_ == ESpawnType::eSpawnOvermap)
{
this->ForkMain();
@ -740,7 +795,7 @@ namespace Aurora::Processes
SysAssert(AuTryInsert(gPidLookupMap, pid, this));
}
return true;
return this->pSemaphore_->WaitOn(250);
}
else
{

View File

@ -101,6 +101,9 @@ namespace Aurora::Processes
AuSInt exitCode_ {};
bool bHasExited {};
AuSPtr<AuLoop::ILSSemaphore> pSemaphore_;
AuList<AuString> envKeysToRemove_;
AuSPtr<IO::CompletionGroup::ICompletionGroup> pCompletionGroup_;
};
}