#define UNICODE #define _UNICODE #include #include #include #include #include #include #include #include #include #include #include #pragma comment(lib, "userenv.lib") #pragma comment(lib, "ole32.lib") static bool GrantContainerFolderAccess(const std::wstring& path, PSID sid) { PACL oldDacl = nullptr; PSECURITY_DESCRIPTOR descriptor = nullptr; DWORD error = GetNamedSecurityInfoW( const_cast(path.c_str()), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nullptr, nullptr, &oldDacl, nullptr, &descriptor); if (error != ERROR_SUCCESS) return false; EXPLICIT_ACCESSW access{}; access.grfAccessPermissions = GENERIC_ALL; access.grfAccessMode = GRANT_ACCESS; access.grfInheritance = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; BuildTrusteeWithSidW(&access.Trustee, sid); PACL updatedDacl = nullptr; error = SetEntriesInAclW(1, &access, oldDacl, &updatedDacl); if (error == ERROR_SUCCESS) { error = SetNamedSecurityInfoW( const_cast(path.c_str()), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, nullptr, nullptr, updatedDacl, nullptr); } if (updatedDacl) LocalFree(updatedDacl); if (descriptor) LocalFree(descriptor); return error == ERROR_SUCCESS; } static std::wstring QuoteArg(const std::wstring& value) { std::wstring out = L"\""; size_t slashes = 0; for (wchar_t ch : value) { if (ch == L'\\') { ++slashes; } else if (ch == L'\"') { out.append(slashes * 2 + 1, L'\\'); out += ch; slashes = 0; } else { out.append(slashes, L'\\'); slashes = 0; out += ch; } } out.append(slashes * 2, L'\\'); out += L'\"'; return out; } static std::vector SafeEnvironmentBlock() { static const wchar_t* const allowed[] = { L"ALLUSERSPROFILE", L"APPDATA", L"COMSPEC", L"HOMEDRIVE", L"HOMEPATH", L"LOCALAPPDATA", L"NUMBER_OF_PROCESSORS", L"OS", L"PATH", L"PATHEXT", L"PROCESSOR_ARCHITECTURE", L"PROCESSOR_IDENTIFIER", L"PROGRAMDATA", L"PROGRAMFILES", L"PROGRAMFILES(X86)", L"PUBLIC", L"SYSTEMDRIVE", L"SYSTEMROOT", L"TEMP", L"TMP", L"USERDOMAIN", L"USERNAME", L"USERPROFILE", L"WINDIR" }; std::vector entries; LPWCH inherited = GetEnvironmentStringsW(); if (!inherited) return {}; for (const wchar_t* item = inherited; *item;) { std::wstring entry(item); item += entry.size() + 1; size_t separator = entry.find(L'='); if (separator == std::wstring::npos || separator == 0) continue; std::wstring key = entry.substr(0, separator); bool keep = false; for (const wchar_t* candidate : allowed) { if (_wcsicmp(key.c_str(), candidate) == 0) { keep = true; break; } } if (keep) entries.push_back(std::move(entry)); } FreeEnvironmentStringsW(inherited); std::sort(entries.begin(), entries.end(), [](const std::wstring& left, const std::wstring& right) { return _wcsicmp(left.c_str(), right.c_str()) < 0; }); std::vector block; for (const auto& entry : entries) { block.insert(block.end(), entry.begin(), entry.end()); block.push_back(L'\0'); } block.push_back(L'\0'); if (entries.empty()) block.push_back(L'\0'); return block; } static void SetEnvironmentValue( std::vector& block, const std::wstring& key, const std::wstring& value) { std::vector entries; for (const wchar_t* item = block.data(); item && *item;) { std::wstring entry(item); item += entry.size() + 1; size_t separator = entry.find(L'='); if (separator == std::wstring::npos || _wcsicmp(entry.substr(0, separator).c_str(), key.c_str()) != 0) { entries.push_back(std::move(entry)); } } entries.push_back(key + L"=" + value); std::sort(entries.begin(), entries.end(), [](const std::wstring& left, const std::wstring& right) { return _wcsicmp(left.c_str(), right.c_str()) < 0; }); block.clear(); for (const auto& entry : entries) { block.insert(block.end(), entry.begin(), entry.end()); block.push_back(L'\0'); } block.push_back(L'\0'); } static bool FilesMatch(const std::wstring& leftPath, const std::wstring& rightPath) { HANDLE left = CreateFileW(leftPath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); HANDLE right = CreateFileW(rightPath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (left == INVALID_HANDLE_VALUE || right == INVALID_HANDLE_VALUE) { if (left != INVALID_HANDLE_VALUE) CloseHandle(left); if (right != INVALID_HANDLE_VALUE) CloseHandle(right); return false; } LARGE_INTEGER leftSize{}, rightSize{}; bool matches = GetFileSizeEx(left, &leftSize) && GetFileSizeEx(right, &rightSize) && leftSize.QuadPart == rightSize.QuadPart && leftSize.QuadPart >= 0 && leftSize.QuadPart <= 1024 * 1024; std::vector leftBytes(matches ? static_cast(leftSize.QuadPart) : 0); std::vector rightBytes(matches ? static_cast(rightSize.QuadPart) : 0); DWORD leftRead = 0, rightRead = 0; if (matches && !leftBytes.empty()) { matches = ReadFile(left, leftBytes.data(), static_cast(leftBytes.size()), &leftRead, nullptr) && ReadFile(right, rightBytes.data(), static_cast(rightBytes.size()), &rightRead, nullptr) && leftRead == static_cast(leftBytes.size()) && rightRead == static_cast(rightBytes.size()) && leftBytes == rightBytes; } CloseHandle(left); CloseHandle(right); return matches; } static constexpr ULONGLONG kMaxPythonRuntimeBytes = 100ull * 1024 * 1024; static constexpr DWORD kMaxPythonRuntimeFiles = 5000; static bool CopyRuntimeFile( const std::wstring& source, const std::wstring& destination, ULONGLONG& copiedBytes, DWORD& copiedFiles ) { WIN32_FILE_ATTRIBUTE_DATA attributes{}; if (!GetFileAttributesExW(source.c_str(), GetFileExInfoStandard, &attributes) || (attributes.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT))) { return false; } const ULONGLONG size = (static_cast(attributes.nFileSizeHigh) << 32) | attributes.nFileSizeLow; if (copiedFiles >= kMaxPythonRuntimeFiles || size > kMaxPythonRuntimeBytes - copiedBytes) { return false; } if (!CopyFileW(source.c_str(), destination.c_str(), FALSE)) return false; copiedBytes += size; ++copiedFiles; return true; } static bool CopyRuntimeTree( const std::wstring& source, const std::wstring& destination, ULONGLONG& copiedBytes, DWORD& copiedFiles, unsigned depth = 0 ) { if (depth > 24 || copiedFiles > kMaxPythonRuntimeFiles) return false; if (!CreateDirectoryW(destination.c_str(), nullptr) && GetLastError() != ERROR_ALREADY_EXISTS) { return false; } WIN32_FIND_DATAW entry{}; HANDLE search = FindFirstFileW((source + L"\\*").c_str(), &entry); if (search == INVALID_HANDLE_VALUE) return false; bool success = true; do { if (wcscmp(entry.cFileName, L".") == 0 || wcscmp(entry.cFileName, L"..") == 0) continue; if (entry.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) continue; const std::wstring sourcePath = source + L"\\" + entry.cFileName; const std::wstring destinationPath = destination + L"\\" + entry.cFileName; if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (wcscmp(entry.cFileName, L"site-packages") == 0 || wcscmp(entry.cFileName, L"__pycache__") == 0 || wcscmp(entry.cFileName, L"test") == 0 || wcscmp(entry.cFileName, L"tests") == 0 || wcscmp(entry.cFileName, L"idlelib") == 0 || wcscmp(entry.cFileName, L"tkinter") == 0 || wcscmp(entry.cFileName, L"ensurepip") == 0) continue; success = CopyRuntimeTree(sourcePath, destinationPath, copiedBytes, copiedFiles, depth + 1); } else { success = CopyRuntimeFile(sourcePath, destinationPath, copiedBytes, copiedFiles); } if (!success) break; } while (FindNextFileW(search, &entry)); const DWORD finalError = GetLastError(); FindClose(search); return success && finalError == ERROR_NO_MORE_FILES; } static constexpr ULONGLONG kMaxSnapshotBytes = 10ull * 1024 * 1024; static constexpr DWORD kMaxSnapshotFiles = 50; static bool SnapshotExtensionAllowed(const std::wstring& name) { const size_t dot = name.find_last_of(L'.'); if (dot == std::wstring::npos) return false; std::wstring extension = name.substr(dot); for (wchar_t& ch : extension) ch = static_cast(towlower(ch)); static const wchar_t* const allowed[] = { L".py", L".dart", L".md", L".txt", L".json", L".yaml", L".yml", L".toml", L".html", L".css", L".js", L".ts", L".tsx", L".jsx", L".sh", L".ps1" }; for (const wchar_t* candidate : allowed) { if (extension == candidate) return true; } return false; } static bool CopySnapshotTree( const std::wstring& source, const std::wstring& destination, ULONGLONG& copiedBytes, DWORD& copiedFiles, unsigned depth = 0 ) { if (depth > 24 || copiedFiles > kMaxSnapshotFiles) return false; const DWORD sourceAttributes = GetFileAttributesW(source.c_str()); if (sourceAttributes == INVALID_FILE_ATTRIBUTES || !(sourceAttributes & FILE_ATTRIBUTE_DIRECTORY) || (sourceAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) return false; if (!CreateDirectoryW(destination.c_str(), nullptr) && GetLastError() != ERROR_ALREADY_EXISTS) { return false; } WIN32_FIND_DATAW entry{}; HANDLE search = FindFirstFileW((source + L"\\*").c_str(), &entry); if (search == INVALID_HANDLE_VALUE) return false; bool success = true; do { if (wcscmp(entry.cFileName, L".") == 0 || wcscmp(entry.cFileName, L"..") == 0) continue; if ((entry.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) || entry.cFileName[0] == L'.') { success = false; break; } const std::wstring sourcePath = source + L"\\" + entry.cFileName; const std::wstring destinationPath = destination + L"\\" + entry.cFileName; if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { success = CopySnapshotTree(sourcePath, destinationPath, copiedBytes, copiedFiles, depth + 1); } else { if (!SnapshotExtensionAllowed(entry.cFileName)) { success = false; break; } WIN32_FILE_ATTRIBUTE_DATA attributes{}; if (!GetFileAttributesExW(sourcePath.c_str(), GetFileExInfoStandard, &attributes) || (attributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { success = false; break; } const ULONGLONG size = (static_cast(attributes.nFileSizeHigh) << 32) | attributes.nFileSizeLow; if (copiedFiles >= kMaxSnapshotFiles || size > kMaxSnapshotBytes - copiedBytes || !CopyFileW(sourcePath.c_str(), destinationPath.c_str(), FALSE)) { success = false; break; } copiedBytes += size; ++copiedFiles; } } while (FindNextFileW(search, &entry)); const DWORD finalError = GetLastError(); FindClose(search); return success && finalError == ERROR_NO_MORE_FILES; } static std::wstring ReadEnvironmentString(const wchar_t* name) { std::vector buffer(32768); DWORD length = GetEnvironmentVariableW(name, buffer.data(), static_cast(buffer.size())); if (length == 0 || length >= buffer.size()) return {}; return std::wstring(buffer.data(), length); } static bool ResolvePythonEntry( const std::wstring& projectRoot, std::wstring relative, std::wstring& resolved ) { if (relative.empty() || relative.size() > 240 || relative.front() == L'/' || relative.front() == L'\\' || relative.find(L':') != std::wstring::npos) return false; for (wchar_t& ch : relative) if (ch == L'\\') ch = L'/'; std::wstring current = projectRoot; size_t start = 0; bool finalPart = false; while (!finalPart) { size_t separator = relative.find(L'/', start); finalPart = separator == std::wstring::npos; const std::wstring part = relative.substr(start, finalPart ? std::wstring::npos : separator - start); if (part.empty() || part == L"." || part == L".." || part.front() == L'.' || part.find_first_of(L"<>|?*\"") != std::wstring::npos) return false; current += L"\\" + part; const DWORD attributes = GetFileAttributesW(current.c_str()); if (attributes == INVALID_FILE_ATTRIBUTES || (attributes & FILE_ATTRIBUTE_REPARSE_POINT)) return false; if (!finalPart && !(attributes & FILE_ATTRIBUTE_DIRECTORY)) return false; if (finalPart && (attributes & FILE_ATTRIBUTE_DIRECTORY)) return false; start = separator + 1; } const size_t dot = relative.find_last_of(L'.'); if (dot == std::wstring::npos) return false; std::wstring extension = relative.substr(dot); for (wchar_t& ch : extension) ch = static_cast(towlower(ch)); if (extension != L".py") return false; resolved = std::move(current); return true; } static bool CopyPythonRuntime( const std::wstring& sourceRoot, const std::wstring& destinationRoot, ULONGLONG& copiedBytes, DWORD& copiedFiles ) { copiedBytes = 0; copiedFiles = 0; if (!CreateDirectoryW(destinationRoot.c_str(), nullptr) && GetLastError() != ERROR_ALREADY_EXISTS) { return false; } static const wchar_t* const runtimeFiles[] = { L"python.exe", L"python3.dll", L"python314.dll", L"vcruntime140.dll", L"vcruntime140_1.dll" }; for (const wchar_t* name : runtimeFiles) { const std::wstring source = sourceRoot + L"\\" + name; const std::wstring destination = destinationRoot + L"\\" + name; WIN32_FILE_ATTRIBUTE_DATA attributes{}; if (!GetFileAttributesExW(source.c_str(), GetFileExInfoStandard, &attributes)) { if (wcscmp(name, L"vcruntime140_1.dll") == 0) continue; return false; } if (!CopyRuntimeFile(source, destination, copiedBytes, copiedFiles)) return false; } return CopyRuntimeTree(sourceRoot + L"\\Lib", destinationRoot + L"\\Lib", copiedBytes, copiedFiles) && CopyRuntimeTree(sourceRoot + L"\\DLLs", destinationRoot + L"\\DLLs", copiedBytes, copiedFiles); } static bool IsSmokeResult(const std::wstring& path) { HANDLE file = CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (file == INVALID_HANDLE_VALUE) return false; char contents[64]{}; DWORD count = 0; bool valid = ReadFile(file, contents, sizeof(contents) - 1, &count, nullptr) && count >= 20 && count < sizeof(contents); CloseHandle(file); const char prefix[] = "sandbox-python:"; valid = valid && count > sizeof(prefix) - 1 && memcmp(contents, prefix, sizeof(prefix) - 1) == 0; bool sawDot = false; for (DWORD index = sizeof(prefix) - 1; valid && index < count; ++index) { if (contents[index] == '.') sawDot = true; else if (contents[index] < '0' || contents[index] > '9') valid = false; } return valid && sawDot; } static bool FileOwnerMatchesSid(const std::wstring& path, PSID expectedSid) { PSID ownerSid = nullptr; PSECURITY_DESCRIPTOR descriptor = nullptr; DWORD error = GetNamedSecurityInfoW( const_cast(path.c_str()), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &ownerSid, nullptr, nullptr, nullptr, &descriptor); const bool matches = error == ERROR_SUCCESS && ownerSid && expectedSid && EqualSid(ownerSid, expectedSid); if (descriptor) LocalFree(descriptor); return matches; } static bool FileOwnerMatchesCurrentUser(const std::wstring& path) { HANDLE token = nullptr; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) return false; DWORD required = 0; GetTokenInformation(token, TokenUser, nullptr, 0, &required); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || required == 0) { CloseHandle(token); return false; } std::vector storage(required); const bool read = GetTokenInformation( token, TokenUser, storage.data(), required, &required) != FALSE; CloseHandle(token); if (!read) return false; auto* user = reinterpret_cast(storage.data()); return FileOwnerMatchesSid(path, user->User.Sid); } static constexpr ULONGLONG kMaxAppContainerDataBytes = 128ull * 1024 * 1024; static bool MeasureDirectoryBytes( const std::wstring& root, ULONGLONG& totalBytes, unsigned depth = 0 ) { if (depth > 48) return false; const DWORD rootAttributes = GetFileAttributesW(root.c_str()); if (rootAttributes == INVALID_FILE_ATTRIBUTES || !(rootAttributes & FILE_ATTRIBUTE_DIRECTORY) || (rootAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) return false; WIN32_FIND_DATAW entry{}; HANDLE search = FindFirstFileW((root + L"\\*").c_str(), &entry); if (search == INVALID_HANDLE_VALUE) return false; bool success = true; do { if (wcscmp(entry.cFileName, L".") == 0 || wcscmp(entry.cFileName, L"..") == 0) continue; if (entry.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { success = false; break; } const std::wstring path = root + L"\\" + entry.cFileName; if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { success = MeasureDirectoryBytes(path, totalBytes, depth + 1); } else { WIN32_FILE_ATTRIBUTE_DATA attributes{}; if (!GetFileAttributesExW(path.c_str(), GetFileExInfoStandard, &attributes) || (attributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { success = false; break; } const ULONGLONG size = (static_cast(attributes.nFileSizeHigh) << 32) | attributes.nFileSizeLow; if (size > (~static_cast(0)) - totalBytes) { success = false; break; } totalBytes += size; } if (!success) break; } while (FindNextFileW(search, &entry)); const DWORD finalError = GetLastError(); FindClose(search); return success && finalError == ERROR_NO_MORE_FILES; } static DWORD RunContainedExe( PSID appContainerSid, const std::wstring& application, const std::wstring& arguments, const wchar_t* environment, const std::wstring& cwd, HANDLE job, std::string* capturedOutput = nullptr, bool* outputTruncated = nullptr, const std::wstring* quotaRoot = nullptr, bool* quotaExceeded = nullptr, ULONGLONG* quotaObservedBytes = nullptr ) { constexpr size_t kMaxCapturedOutput = 64 * 1024; const bool capture = capturedOutput != nullptr; if (capturedOutput) capturedOutput->clear(); if (outputTruncated) *outputTruncated = false; if (quotaExceeded) *quotaExceeded = false; if (quotaObservedBytes) *quotaObservedBytes = 0; if (quotaRoot) { ULONGLONG currentBytes = 0; const bool measured = MeasureDirectoryBytes(*quotaRoot, currentBytes); if (quotaObservedBytes) *quotaObservedBytes = currentBytes; if (!measured || currentBytes > kMaxAppContainerDataBytes) { if (quotaExceeded) *quotaExceeded = true; return ERROR_DISK_FULL; } } HANDLE pipeRead = nullptr; HANDLE pipeWrite = nullptr; HANDLE nullInput = nullptr; if (capture) { SECURITY_ATTRIBUTES pipeSecurity{sizeof(SECURITY_ATTRIBUTES), nullptr, TRUE}; if (!CreatePipe(&pipeRead, &pipeWrite, &pipeSecurity, 0) || !SetHandleInformation(pipeRead, HANDLE_FLAG_INHERIT, 0)) { DWORD error = GetLastError(); if (pipeRead) CloseHandle(pipeRead); if (pipeWrite) CloseHandle(pipeWrite); return error; } nullInput = CreateFileW(L"NUL", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, &pipeSecurity, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (nullInput == INVALID_HANDLE_VALUE) { DWORD error = GetLastError(); CloseHandle(pipeRead); CloseHandle(pipeWrite); return error; } } const DWORD attributeCount = capture ? 2 : 1; SIZE_T attributeBytes = 0; InitializeProcThreadAttributeList(nullptr, attributeCount, 0, &attributeBytes); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { DWORD error = GetLastError(); if (pipeRead) CloseHandle(pipeRead); if (pipeWrite) CloseHandle(pipeWrite); if (nullInput) CloseHandle(nullInput); return error; } auto* attributes = static_cast( HeapAlloc(GetProcessHeap(), 0, attributeBytes) ); if (!attributes) { if (pipeRead) CloseHandle(pipeRead); if (pipeWrite) CloseHandle(pipeWrite); if (nullInput) CloseHandle(nullInput); return ERROR_OUTOFMEMORY; } if (!InitializeProcThreadAttributeList(attributes, attributeCount, 0, &attributeBytes)) { DWORD error = GetLastError(); HeapFree(GetProcessHeap(), 0, attributes); if (pipeRead) CloseHandle(pipeRead); if (pipeWrite) CloseHandle(pipeWrite); if (nullInput) CloseHandle(nullInput); return error; } SECURITY_CAPABILITIES security{}; security.AppContainerSid = appContainerSid; security.Capabilities = nullptr; security.CapabilityCount = 0; if (!UpdateProcThreadAttribute( attributes, 0, PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES, &security, sizeof(security), nullptr, nullptr)) { DWORD error = GetLastError(); DeleteProcThreadAttributeList(attributes); HeapFree(GetProcessHeap(), 0, attributes); if (pipeRead) CloseHandle(pipeRead); if (pipeWrite) CloseHandle(pipeWrite); if (nullInput) CloseHandle(nullInput); return error; } if (capture) { HANDLE inheritedHandles[] = {nullInput, pipeWrite}; if (!UpdateProcThreadAttribute( attributes, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, inheritedHandles, sizeof(inheritedHandles), nullptr, nullptr)) { DWORD error = GetLastError(); DeleteProcThreadAttributeList(attributes); HeapFree(GetProcessHeap(), 0, attributes); CloseHandle(pipeRead); CloseHandle(pipeWrite); CloseHandle(nullInput); return error; } } STARTUPINFOEXW startup{}; startup.StartupInfo.cb = sizeof(startup); startup.StartupInfo.dwFlags = STARTF_USESHOWWINDOW; startup.StartupInfo.wShowWindow = SW_HIDE; if (capture) { startup.StartupInfo.dwFlags |= STARTF_USESTDHANDLES; startup.StartupInfo.hStdInput = nullInput; startup.StartupInfo.hStdOutput = pipeWrite; startup.StartupInfo.hStdError = pipeWrite; } startup.lpAttributeList = attributes; PROCESS_INFORMATION process{}; std::wstring commandLine = QuoteArg(application); if (!arguments.empty()) commandLine += L" " + arguments; std::wstring mutableLine = commandLine; constexpr DWORD flags = EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT | CREATE_NO_WINDOW | CREATE_SUSPENDED; BOOL created = CreateProcessW( application.c_str(), mutableLine.empty() ? nullptr : &mutableLine[0], nullptr, nullptr, capture ? TRUE : FALSE, flags, const_cast(environment), cwd.c_str(), &startup.StartupInfo, &process ); DWORD error = created ? ERROR_SUCCESS : GetLastError(); DeleteProcThreadAttributeList(attributes); HeapFree(GetProcessHeap(), 0, attributes); if (pipeWrite) CloseHandle(pipeWrite); if (nullInput) CloseHandle(nullInput); if (!created) { if (pipeRead) CloseHandle(pipeRead); return error; } if (!AssignProcessToJobObject(job, process.hProcess)) { error = GetLastError(); TerminateProcess(process.hProcess, error); CloseHandle(process.hThread); CloseHandle(process.hProcess); if (pipeRead) CloseHandle(pipeRead); return error; } ResumeThread(process.hThread); DWORD exitCode = ERROR_TIMEOUT; if (capture) { const ULONGLONG deadline = GetTickCount64() + 30000; ULONGLONG nextQuotaCheck = GetTickCount64() + 25; bool processFinished = false; bool pipeFinished = false; while (!pipeFinished || !processFinished) { DWORD available = 0; if (!pipeFinished && PeekNamedPipe(pipeRead, nullptr, 0, nullptr, &available, nullptr)) { while (available > 0) { char buffer[4096]; DWORD bytesRead = 0; const DWORD requested = (std::min)(available, static_cast(sizeof(buffer))); if (!ReadFile(pipeRead, buffer, requested, &bytesRead, nullptr) || bytesRead == 0) { pipeFinished = true; break; } const size_t remaining = capturedOutput->size() < kMaxCapturedOutput ? kMaxCapturedOutput - capturedOutput->size() : 0; const size_t retained = (std::min)(remaining, static_cast(bytesRead)); capturedOutput->append(buffer, retained); if (retained < bytesRead && outputTruncated) *outputTruncated = true; available -= bytesRead; } } else if (GetLastError() == ERROR_BROKEN_PIPE) { pipeFinished = true; } if (!processFinished && WaitForSingleObject(process.hProcess, 0) == WAIT_OBJECT_0) { GetExitCodeProcess(process.hProcess, &exitCode); processFinished = true; TerminateJobObject(job, ERROR_SUCCESS); } if (!processFinished && quotaRoot && GetTickCount64() >= nextQuotaCheck) { ULONGLONG currentBytes = 0; const bool measured = MeasureDirectoryBytes(*quotaRoot, currentBytes); if (quotaObservedBytes) *quotaObservedBytes = currentBytes; if (!measured || currentBytes > kMaxAppContainerDataBytes) { if (quotaExceeded) *quotaExceeded = true; TerminateJobObject(job, ERROR_DISK_FULL); exitCode = ERROR_DISK_FULL; processFinished = WaitForSingleObject(process.hProcess, 5000) == WAIT_OBJECT_0; pipeFinished = false; } nextQuotaCheck = GetTickCount64() + 25; } if (!processFinished && GetTickCount64() >= deadline) { TerminateJobObject(job, ERROR_TIMEOUT); exitCode = ERROR_TIMEOUT; processFinished = WaitForSingleObject(process.hProcess, 5000) == WAIT_OBJECT_0; pipeFinished = false; } if (!pipeFinished || !processFinished) Sleep(20); if (processFinished && pipeFinished) break; } } else { DWORD waitResult = WaitForSingleObject(process.hProcess, 30000); if (waitResult == WAIT_OBJECT_0) { GetExitCodeProcess(process.hProcess, &exitCode); } else { TerminateJobObject(job, ERROR_TIMEOUT); } } CloseHandle(process.hThread); CloseHandle(process.hProcess); if (pipeRead) CloseHandle(pipeRead); return exitCode; } static DWORD RunContained( PSID appContainerSid, const std::wstring& command, const wchar_t* environment, const std::wstring& cwd, HANDLE job ) { const std::wstring shell = L"C:\\Windows\\System32\\cmd.exe"; return RunContainedExe(appContainerSid, shell, L"/d /s /c \"" + command + L"\"", environment, cwd, job); } int wmain() { wchar_t tempPath[MAX_PATH]{}; if (!GetTempPathW(MAX_PATH, tempPath)) return 10; GUID id{}; if (FAILED(CoCreateGuid(&id))) return 11; wchar_t idText[40]{}; if (StringFromGUID2(id, idText, 40) == 0) return 12; std::wstring nonce = idText; if (!nonce.empty() && nonce.front() == L'{') nonce.erase(nonce.begin()); if (!nonce.empty() && nonce.back() == L'}') nonce.pop_back(); std::wstring profileName = L"SovereignAIProbe" + nonce; std::wstring secretPath = std::wstring(tempPath) + L"SovereignAIProbe" + nonce + L".txt"; std::wstring writePath = std::wstring(tempPath) + L"SovereignAIProbe" + nonce + L"-write.txt"; const char marker[] = "host-secret-must-stay-private"; HANDLE secret = CreateFileW(secretPath.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, nullptr); if (secret == INVALID_HANDLE_VALUE) return 13; DWORD bytesWritten = 0; if (!WriteFile(secret, marker, sizeof(marker) - 1, &bytesWritten, nullptr) || bytesWritten != sizeof(marker) - 1) { CloseHandle(secret); return 14; } CloseHandle(secret); PSID appContainerSid = nullptr; HRESULT profileResult = CreateAppContainerProfile( profileName.c_str(), L"SovereignAI isolated command probe", L"Temporary test profile for command isolation", nullptr, 0, &appContainerSid); if (FAILED(profileResult)) { fwprintf(stderr, L"CreateAppContainerProfile failed: 0x%08lx (Win32 %lu)\n", static_cast(profileResult), static_cast(HRESULT_CODE(profileResult))); DeleteFileW(secretPath.c_str()); return static_cast(HRESULT_CODE(profileResult)); } LPWSTR sidText = nullptr; PWSTR appContainerFolder = nullptr; bool appContainerPathReady = ConvertSidToStringSidW(appContainerSid, &sidText) && SUCCEEDED(GetAppContainerFolderPath(sidText, &appContainerFolder)); if (!appContainerPathReady) { FreeSid(appContainerSid); DeleteAppContainerProfile(profileName.c_str()); DeleteFileW(secretPath.c_str()); return 16; } if (sidText) LocalFree(sidText); HANDLE job = CreateJobObjectW(nullptr, nullptr); JOBOBJECT_EXTENDED_LIMIT_INFORMATION limits{}; limits.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_ACTIVE_PROCESS | JOB_OBJECT_LIMIT_JOB_MEMORY; limits.BasicLimitInformation.ActiveProcessLimit = 8; limits.JobMemoryLimit = 512ull * 1024 * 1024; bool jobReady = job && SetInformationJobObject( job, JobObjectExtendedLimitInformation, &limits, sizeof(limits)); JOBOBJECT_IO_RATE_CONTROL_INFORMATION ioLimits{}; ioLimits.MaxBandwidth = 8ll * 1024 * 1024; ioLimits.ControlFlags = JOB_OBJECT_IO_RATE_CONTROL_ENABLE; DWORD jobIoControlResult = jobReady ? SetIoRateControlInformationJobObject(job, &ioLimits) : ERROR_INVALID_HANDLE; DWORD jobIoControlError = jobIoControlResult == 0 ? GetLastError() : ERROR_SUCCESS; auto environment = SafeEnvironmentBlock(); if (environment.empty()) return 15; std::wstring appDataPath(appContainerFolder); std::wstring appTempPath = appDataPath + L"\\Temp"; std::wstring sandboxWorkspacePath = appDataPath + L"\\agent-workspace"; std::wstring projectSnapshotPath = sandboxWorkspacePath + L"\\project"; std::wstring stagedInputPath = projectSnapshotPath + L"\\README.md"; std::wstring stagedCopyPath = projectSnapshotPath + L"\\staged-copy.md"; std::wstring pythonSandboxPath = sandboxWorkspacePath + L"\\python"; std::wstring pythonVersionPath = projectSnapshotPath + L"\\scripts\\execution-result.txt"; CreateDirectoryW(appTempPath.c_str(), nullptr); bool workspaceFolderReady = CreateDirectoryW(sandboxWorkspacePath.c_str(), nullptr) != FALSE || GetLastError() == ERROR_ALREADY_EXISTS; workspaceFolderReady = workspaceFolderReady && GrantContainerFolderAccess(sandboxWorkspacePath, appContainerSid); const std::wstring hostSnapshotPath = ReadEnvironmentString(L"SOVEREIGNAI_STAGING_ROOT"); const std::wstring requestedEntry = ReadEnvironmentString(L"SOVEREIGNAI_ENTRY_SCRIPT"); ULONGLONG stagedBytes = 0; DWORD stagedFiles = 0; bool stagedInputCopied = workspaceFolderReady && !hostSnapshotPath.empty() && CopySnapshotTree(hostSnapshotPath, projectSnapshotPath, stagedBytes, stagedFiles); std::wstring pythonEntryPath; bool entryScriptReady = stagedInputCopied && ResolvePythonEntry(projectSnapshotPath, requestedEntry, pythonEntryPath); std::wstring curlPath = sandboxWorkspacePath + L"\\curl.exe"; bool curlCopied = workspaceFolderReady && CopyFileW(L"C:\\Windows\\System32\\curl.exe", curlPath.c_str(), FALSE); wchar_t pythonRootBuffer[32768]{}; DWORD pythonRootLength = GetEnvironmentVariableW( L"SOVEREIGNAI_PYTHON_HOME", pythonRootBuffer, 32768); std::wstring pythonSourcePath = pythonRootLength > 0 && pythonRootLength < 32768 ? std::wstring(pythonRootBuffer, pythonRootLength) : std::wstring(); ULONGLONG pythonRuntimeBytes = 0; DWORD pythonRuntimeFiles = 0; bool pythonRuntimeCopied = workspaceFolderReady && !pythonSourcePath.empty() && CopyPythonRuntime(pythonSourcePath, pythonSandboxPath, pythonRuntimeBytes, pythonRuntimeFiles); bool pythonProbeReady = pythonRuntimeCopied && entryScriptReady; SetEnvironmentValue(environment, L"PATH", L"C:\\Windows\\System32"); SetEnvironmentValue(environment, L"APPDATA", appDataPath); SetEnvironmentValue(environment, L"LOCALAPPDATA", appDataPath); SetEnvironmentValue(environment, L"TEMP", appTempPath); SetEnvironmentValue(environment, L"TMP", appTempPath); SetEnvironmentValue(environment, L"USERPROFILE", appDataPath); SetEnvironmentValue(environment, L"HOMEDRIVE", appDataPath.substr(0, 2)); SetEnvironmentValue(environment, L"HOMEPATH", appDataPath.size() > 2 ? appDataPath.substr(2) : L"\\"); SetEnvironmentValue(environment, L"PATH", pythonSandboxPath + L"\\DLLs;" + pythonSandboxPath + L";C:\\Windows\\System32"); SetEnvironmentValue(environment, L"PYTHONHOME", pythonSandboxPath); SetEnvironmentValue(environment, L"PYTHONNOUSERSITE", L"1"); SetEnvironmentValue(environment, L"PYTHONDONTWRITEBYTECODE", L"1"); SetEnvironmentValue(environment, L"PYTHONUTF8", L"1"); std::wstring cwd = L"C:\\Windows\\System32"; DWORD shellResult = jobReady ? RunContained(appContainerSid, L"exit 0", environment.data(), cwd, job) : GetLastError(); std::wstring readAttempt = L"type " + secretPath + L" >nul 2>nul"; DWORD readResult = jobReady ? RunContained(appContainerSid, readAttempt, environment.data(), cwd, job) : ERROR_INVALID_HANDLE; std::wstring writeAttempt = L"echo modified>" + writePath + L" 2>nul"; DWORD writeResult = jobReady ? RunContained(appContainerSid, writeAttempt, environment.data(), cwd, job) : ERROR_INVALID_HANDLE; std::wstring allowedWritePath = sandboxWorkspacePath + L"\\probe-output.txt"; DWORD allowedWriteResult = jobReady && workspaceFolderReady ? RunContained(appContainerSid, L"echo contained>" + allowedWritePath, environment.data(), cwd, job) : ERROR_INVALID_HANDLE; std::wstring stagedFileUrl = L"file:///"; for (wchar_t ch : stagedInputPath) { stagedFileUrl += ch == L'\\' ? L'/' : ch; } DWORD stagedReadResult = jobReady && stagedInputCopied && curlCopied ? RunContained(appContainerSid, QuoteArg(curlPath) + L" --fail --silent " + stagedFileUrl + L" -o " + stagedCopyPath, environment.data(), cwd, job) : ERROR_INVALID_HANDLE; std::wstring pythonExecutable = pythonSandboxPath + L"\\python.exe"; std::string pythonOutput; bool pythonOutputTruncated = false; DWORD pythonRunResult = jobReady && pythonProbeReady ? RunContainedExe(appContainerSid, pythonExecutable, L"-s " + QuoteArg(pythonEntryPath), environment.data(), cwd, job, &pythonOutput, &pythonOutputTruncated) : ERROR_INVALID_HANDLE; std::string overflowOutput; bool overflowTruncated = false; DWORD overflowRunResult = jobReady && pythonRuntimeCopied ? RunContainedExe(appContainerSid, pythonExecutable, L"-s -c " + QuoteArg(L"print('x' * 70000)"), environment.data(), cwd, job, &overflowOutput, &overflowTruncated) : ERROR_INVALID_HANDLE; DWORD curlVersionResult = jobReady && curlCopied ? RunContained(appContainerSid, QuoteArg(curlPath) + L" --version", environment.data(), cwd, job) : ERROR_INVALID_HANDLE; DWORD curlNetworkResult = jobReady && curlCopied ? RunContained(appContainerSid, QuoteArg(curlPath) + L" --noproxy \"*\" --max-time 4 http://127.0.0.1:8100/health -o NUL", environment.data(), cwd, job) : ERROR_INVALID_HANDLE; std::wstring diskFillScriptPath; bool diskFillScriptReady = stagedInputCopied && ResolvePythonEntry( projectSnapshotPath, L"scripts/appcontainer_disk_fill_smoke.py", diskFillScriptPath); std::string diskFillOutput; bool diskFillOutputTruncated = false; bool diskQuotaExceeded = false; ULONGLONG diskQuotaObservedBytes = 0; DWORD diskFillRunResult = jobReady && pythonRuntimeCopied && diskFillScriptReady ? RunContainedExe(appContainerSid, pythonExecutable, L"-s " + QuoteArg(diskFillScriptPath), environment.data(), cwd, job, &diskFillOutput, &diskFillOutputTruncated, &appDataPath, &diskQuotaExceeded, &diskQuotaObservedBytes) : ERROR_INVALID_HANDLE; DWORD attrs = GetFileAttributesW(writePath.c_str()); DWORD attrsError = attrs == INVALID_FILE_ATTRIBUTES ? GetLastError() : ERROR_SUCCESS; bool hostSecretPreserved = false; secret = CreateFileW(secretPath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (secret != INVALID_HANDLE_VALUE) { char check[sizeof(marker)]{}; DWORD bytesRead = 0; hostSecretPreserved = ReadFile(secret, check, sizeof(marker) - 1, &bytesRead, nullptr) && bytesRead == sizeof(marker) - 1 && memcmp(check, marker, sizeof(marker) - 1) == 0; CloseHandle(secret); } bool allowedWorkspaceWriteVisible = false; HANDLE allowedOutput = CreateFileW(allowedWritePath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); if (allowedOutput != INVALID_HANDLE_VALUE) { char contents[32]{}; DWORD count = 0; allowedWorkspaceWriteVisible = ReadFile(allowedOutput, contents, sizeof(contents) - 1, &count, nullptr) && count >= 9 && memcmp(contents, "contained", 9) == 0; CloseHandle(allowedOutput); } bool stagedInputRoundTripMatches = stagedInputCopied && FilesMatch( L"README.md", stagedCopyPath); bool pythonVersionVisible = IsSmokeResult(pythonVersionPath); const std::wstring pythonResultPath = projectSnapshotPath + L"\\scripts\\execution-result.txt"; const bool pythonResultOwnedByAppContainer = FileOwnerMatchesSid(pythonResultPath, appContainerSid); const bool pythonResultOwnedByHostUser = FileOwnerMatchesCurrentUser(pythonResultPath); if (job) CloseHandle(job); if (appContainerFolder) CoTaskMemFree(appContainerFolder); FreeSid(appContainerSid); DeleteFileW(curlPath.c_str()); DeleteFileW(stagedInputPath.c_str()); DeleteFileW(stagedCopyPath.c_str()); DeleteFileW(pythonVersionPath.c_str()); DeleteAppContainerProfile(profileName.c_str()); DeleteFileW(secretPath.c_str()); DeleteFileW(writePath.c_str()); DeleteFileW(allowedWritePath.c_str()); bool writeWasBlocked = attrs == INVALID_FILE_ATTRIBUTES && (attrsError == ERROR_FILE_NOT_FOUND || attrsError == ERROR_ACCESS_DENIED); wprintf(L"shell_exit=%lu\nread_host_file_exit=%lu\nwrite_host_file_exit=%lu\nhost_secret_preserved=%s\nwrite_artifact_absent=%s\n", shellResult, readResult, writeResult, hostSecretPreserved ? L"true" : L"false", writeWasBlocked ? L"true" : L"false"); wprintf(L"profile_write_exit=%lu\nprofile_write_visible=%s\n", allowedWriteResult, allowedWorkspaceWriteVisible ? L"true" : L"false"); wprintf(L"staged_copy_exit=%lu\nstaged_input_copied=%s\nstaged_files=%lu\nstaged_bytes=%llu\nstaged_roundtrip_matches=%s\n", stagedReadResult, stagedInputCopied ? L"true" : L"false", stagedFiles, stagedBytes, stagedInputRoundTripMatches ? L"true" : L"false"); wprintf(L"python_runtime_copied=%s\npython_runtime_bytes=%llu\npython_runtime_files=%lu\nentry_script_valid=%s\npython_run_exit=%lu\npython_result_written=%s\n", pythonRuntimeCopied ? L"true" : L"false", pythonRuntimeBytes, pythonRuntimeFiles, entryScriptReady ? L"true" : L"false", pythonRunResult, pythonVersionVisible ? L"true" : L"false"); wprintf(L"python_result_owner_is_appcontainer_sid=%s\npython_result_owner_is_host_user_sid=%s\n", pythonResultOwnedByAppContainer ? L"true" : L"false", pythonResultOwnedByHostUser ? L"true" : L"false"); std::vector pythonOutputWide(pythonOutput.size() + 1); bool pythonOutputValidUtf8 = true; if (!pythonOutput.empty()) { int wideCount = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, pythonOutput.data(), static_cast(pythonOutput.size()), pythonOutputWide.data(), static_cast(pythonOutputWide.size())); if (wideCount <= 0) { pythonOutputValidUtf8 = false; wideCount = MultiByteToWideChar(CP_UTF8, 0, pythonOutput.data(), static_cast(pythonOutput.size()), pythonOutputWide.data(), static_cast(pythonOutputWide.size())); } if (wideCount > 0) pythonOutputWide[wideCount] = L'\0'; else pythonOutputWide[0] = L'\0'; } const bool pythonOutputHasReplacement = std::wstring(pythonOutputWide.data()).find(L'\uFFFD') != std::wstring::npos; wprintf(L"python_output_bytes=%llu\npython_output_truncated=%s\npython_output_valid_utf8=%s\npython_output_replacement_present=%s\npython_output=%ls\n", static_cast(pythonOutput.size()), pythonOutputTruncated ? L"true" : L"false", pythonOutputValidUtf8 ? L"true" : L"false", pythonOutputHasReplacement ? L"true" : L"false", pythonOutputWide.data()); wprintf(L"overflow_run_exit=%lu\noverflow_output_bytes=%llu\noverflow_truncated=%s\n", overflowRunResult, static_cast(overflowOutput.size()), overflowTruncated ? L"true" : L"false"); wprintf(L"curl_version_exit=%lu\ncurl_local_health_exit=%lu\n", curlVersionResult, curlNetworkResult); wprintf(L"disk_fill_script_valid=%s\ndisk_fill_exit=%lu\ndisk_quota_limit_bytes=%llu\ndisk_quota_observed_bytes=%llu\ndisk_quota_exceeded=%s\n", diskFillScriptReady ? L"true" : L"false", diskFillRunResult, kMaxAppContainerDataBytes, diskQuotaObservedBytes, diskQuotaExceeded ? L"true" : L"false"); wprintf(L"job_io_rate_control_set=%s\njob_io_rate_control_error=%lu\n", jobIoControlResult != 0 ? L"true" : L"false", jobIoControlError); if (!jobReady || shellResult != 0 || readResult == 0 || writeResult == 0 || !hostSecretPreserved || !writeWasBlocked || !workspaceFolderReady || allowedWriteResult != 0 || !allowedWorkspaceWriteVisible || !stagedInputCopied || stagedReadResult != 0 || !stagedInputRoundTripMatches || !pythonRuntimeCopied || !pythonProbeReady || pythonRunResult != 0 || !pythonVersionVisible || pythonOutputValidUtf8 || !pythonOutputHasReplacement || overflowRunResult != 0 || overflowOutput.size() != 64 * 1024 || !overflowTruncated || !curlCopied || curlVersionResult != 0 || curlNetworkResult == 0 || !diskFillScriptReady || diskFillRunResult != ERROR_DISK_FULL || !diskQuotaExceeded || diskQuotaObservedBytes <= kMaxAppContainerDataBytes) return 20; return 0; }