From db233d363aff2542e9fd738f1bbe43ea80148d13 Mon Sep 17 00:00:00 2001 From: J Reece Wilson Date: Mon, 5 Aug 2024 22:13:02 +0100 Subject: [PATCH] [*] POSIX: AuProcesses mustn't allocate (sorta) while in a COW address space (including accessing bad CRT apis) --- Source/Processes/AuProcess.Unix.cpp | 127 ++++++++++++++++++++-------- Source/Processes/AuProcess.Unix.hpp | 3 + 2 files changed, 94 insertions(+), 36 deletions(-) diff --git a/Source/Processes/AuProcess.Unix.cpp b/Source/Processes/AuProcess.Unix.cpp index f6a391d8..d1b1c847 100644 --- a/Source/Processes/AuProcess.Unix.cpp +++ b/Source/Processes/AuProcess.Unix.cpp @@ -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(); - if (!this->loopSource_) + if (!AuFS::FileExists(this->startup_.process)) { + SysPushErrorIO("No Process Module / Missing File"); return false; } + this->loopSource_ = AuMakeShared(); + 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 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(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(this->startup_.process.size() + 1); + AuMemcpy(pProcessPath, this->startup_.process.c_str(), this->startup_.process.size()); + + auto pArgsBlock = heapObject->ZAlloc((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(uLength); + AuMemcpy(pArg, pString, uLength); + pArgsBlock[i] = pArg; + } + } + + auto pEnvArgsBlock = heapObject->ZAlloc((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(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 { diff --git a/Source/Processes/AuProcess.Unix.hpp b/Source/Processes/AuProcess.Unix.hpp index c381f2d9..54786b9f 100644 --- a/Source/Processes/AuProcess.Unix.hpp +++ b/Source/Processes/AuProcess.Unix.hpp @@ -101,6 +101,9 @@ namespace Aurora::Processes AuSInt exitCode_ {}; bool bHasExited {}; + AuSPtr pSemaphore_; + AuList envKeysToRemove_; + AuSPtr pCompletionGroup_; }; } \ No newline at end of file