[*] 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_.fwdErr, this->pipeStdErr_, AuIO::EStandardStream::eErrorStream, this->startup_.handleErrorStream);
InitProcessStdHandles(this->startup_.fwdIn, this->pipeStdIn_, AuIO::EStandardStream::eInputStream, this->startup_.handleInputStream); InitProcessStdHandles(this->startup_.fwdIn, this->pipeStdIn_, AuIO::EStandardStream::eInputStream, this->startup_.handleInputStream);
this->loopSource_ = AuMakeShared<ProcessAliveLoopSource>(); if (!AuFS::FileExists(this->startup_.process))
if (!this->loopSource_)
{ {
SysPushErrorIO("No Process Module / Missing File");
return false; return false;
} }
this->finished_ = AuThreadPrimitives::EventShared(false, false, true); 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_) if (!this->finished_)
{ {
SysPushErrorIO("No sync");
return false; return false;
} }
@ -561,6 +591,16 @@ namespace Aurora::Processes
{ {
PosixDoForkHooks(); 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); ::dup2(this->pipeStdIn_[0], STDIN_FILENO);
::close(this->pipeStdIn_[0]); ::close(this->pipeStdIn_[0]);
@ -588,32 +628,6 @@ namespace Aurora::Processes
::setsid(); ::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 defined(AURORA_IS_XNU_DERIVED)
if (this->startup_.workingDirectory) if (this->startup_.workingDirectory)
{ {
@ -659,7 +673,7 @@ namespace Aurora::Processes
#elif defined(AURORA_IS_POSIX_DERIVED) #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); cpuset_init(cpuSet);
@ -672,7 +686,7 @@ namespace Aurora::Processes
pthread_setaffinity_np(pthread_self(), cpuset_size(cpuSet), cpuSet); pthread_setaffinity_np(pthread_self(), cpuset_size(cpuSet), cpuSet);
cpuset_free(cpuSet); //cpuset_free(cpuSet);
} }
#else #else
@ -687,15 +701,56 @@ namespace Aurora::Processes
this->startup_.posixApplySandboxCOW(); this->startup_.posixApplySandboxCOW();
} }
::execv(this->startup_.process.c_str(), (char * const *)this->cargs_.data()); // https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html auto pProcessPath = heapObject->ZAlloc<char *>(this->startup_.process.size() + 1);
AuMemcpy(pProcessPath, this->startup_.process.c_str(), this->startup_.process.size());
SysPushErrorGen("execv didn't overwrite the process map. Launch: {} ({})", this->startup_.process, this->debug_); 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() bool ProcessImpl::Start()
{ {
this->exitCode_ = 0x10110100; 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) if (this->type_ == ESpawnType::eSpawnOvermap)
{ {
this->ForkMain(); this->ForkMain();
@ -740,7 +795,7 @@ namespace Aurora::Processes
SysAssert(AuTryInsert(gPidLookupMap, pid, this)); SysAssert(AuTryInsert(gPidLookupMap, pid, this));
} }
return true; return this->pSemaphore_->WaitOn(250);
} }
else else
{ {

View File

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