Run Python smoke code in AppContainer

This commit is contained in:
Hamza Ayed
2026-10-03 13:08:12 +03:00
parent fbbfa3a2d4
commit fc4e9ee40f
3 changed files with 188 additions and 5 deletions
@@ -154,9 +154,126 @@ static bool FilesMatch(const std::wstring& leftPath, const std::wstring& rightPa
return matches;
}
static DWORD RunContained(
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<ULONGLONG>(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 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 WriteFileBytes(const std::wstring& path, const char* bytes, DWORD length) {
HANDLE file = CreateFileW(path.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, nullptr);
if (file == INVALID_HANDLE_VALUE) return false;
DWORD written = 0;
bool success = WriteFile(file, bytes, length, &written, nullptr) && written == length;
CloseHandle(file);
return success;
}
static bool IsVersionText(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 >= 5 && count < sizeof(contents);
CloseHandle(file);
bool sawDot = false;
for (DWORD index = 0; valid && index < count; ++index) {
if (contents[index] == '.') sawDot = true;
else if (contents[index] < '0' || contents[index] > '9') valid = false;
}
return valid && sawDot;
}
static DWORD RunContainedExe(
PSID appContainerSid,
const std::wstring& command,
const std::wstring& application,
const std::wstring& arguments,
const wchar_t* environment,
const std::wstring& cwd,
HANDLE job
@@ -200,14 +317,14 @@ static DWORD RunContained(
startup.StartupInfo.wShowWindow = SW_HIDE;
startup.lpAttributeList = attributes;
PROCESS_INFORMATION process{};
std::wstring commandLine = QuoteArg(L"C:\\Windows\\System32\\cmd.exe") +
L" /d /s /c \"" + command + L"\"";
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(
L"C:\\Windows\\System32\\cmd.exe",
application.c_str(),
mutableLine.empty() ? nullptr : &mutableLine[0],
nullptr,
nullptr,
@@ -243,6 +360,18 @@ static DWORD RunContained(
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;
@@ -307,6 +436,9 @@ int wmain() {
std::wstring sandboxWorkspacePath = appDataPath + L"\\agent-workspace";
std::wstring stagedInputPath = sandboxWorkspacePath + L"\\README.md";
std::wstring stagedCopyPath = sandboxWorkspacePath + L"\\staged-copy.md";
std::wstring pythonSandboxPath = sandboxWorkspacePath + L"\\python";
std::wstring pythonProbePath = sandboxWorkspacePath + L"\\python_probe.py";
std::wstring pythonVersionPath = sandboxWorkspacePath + L"\\python-version.txt";
CreateDirectoryW(appTempPath.c_str(), nullptr);
bool workspaceFolderReady = CreateDirectoryW(sandboxWorkspacePath.c_str(), nullptr) != FALSE ||
GetLastError() == ERROR_ALREADY_EXISTS;
@@ -317,11 +449,36 @@ int wmain() {
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);
const char pythonSource[] =
"import pathlib, sys\n"
"pathlib.Path(__file__).with_name('python-version.txt').write_text(\n"
" '.'.join(map(str, sys.version_info[:3])), encoding='ascii')\n";
bool pythonProbeWritten = pythonRuntimeCopied &&
WriteFileBytes(pythonProbePath, pythonSource, sizeof(pythonSource) - 1);
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");
std::wstring cwd = L"C:\\Windows\\System32";
DWORD shellResult = jobReady
? RunContained(appContainerSid, L"exit 0", environment.data(), cwd, job)
@@ -347,6 +504,11 @@ int wmain() {
? 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";
DWORD pythonRunResult = jobReady && pythonProbeWritten
? RunContainedExe(appContainerSid, pythonExecutable,
L"-s " + QuoteArg(pythonProbePath), environment.data(), cwd, job)
: ERROR_INVALID_HANDLE;
DWORD curlVersionResult = jobReady && curlCopied
? RunContained(appContainerSid, QuoteArg(curlPath) + L" --version",
environment.data(), cwd, job)
@@ -381,6 +543,7 @@ int wmain() {
}
bool stagedInputRoundTripMatches = stagedInputCopied && FilesMatch(
L"README.md", stagedCopyPath);
bool pythonVersionVisible = IsVersionText(pythonVersionPath);
if (job) CloseHandle(job);
if (appContainerFolder) CoTaskMemFree(appContainerFolder);
@@ -388,6 +551,8 @@ int wmain() {
DeleteFileW(curlPath.c_str());
DeleteFileW(stagedInputPath.c_str());
DeleteFileW(stagedCopyPath.c_str());
DeleteFileW(pythonProbePath.c_str());
DeleteFileW(pythonVersionPath.c_str());
DeleteAppContainerProfile(profileName.c_str());
DeleteFileW(secretPath.c_str());
DeleteFileW(writePath.c_str());
@@ -404,12 +569,17 @@ int wmain() {
wprintf(L"staged_copy_exit=%lu\nstaged_input_copied=%s\nstaged_roundtrip_matches=%s\n",
stagedReadResult, stagedInputCopied ? L"true" : L"false",
stagedInputRoundTripMatches ? L"true" : L"false");
wprintf(L"python_runtime_copied=%s\npython_runtime_bytes=%llu\npython_runtime_files=%lu\npython_run_exit=%lu\npython_version_written=%s\n",
pythonRuntimeCopied ? L"true" : L"false", pythonRuntimeBytes,
pythonRuntimeFiles, pythonRunResult, pythonVersionVisible ? L"true" : L"false");
wprintf(L"curl_version_exit=%lu\ncurl_local_health_exit=%lu\n",
curlVersionResult, curlNetworkResult);
if (!jobReady || shellResult != 0 || readResult == 0 || writeResult == 0 ||
!hostSecretPreserved || !writeWasBlocked || !workspaceFolderReady ||
allowedWriteResult != 0 || !allowedWorkspaceWriteVisible ||
!stagedInputCopied || stagedReadResult != 0 || !stagedInputRoundTripMatches ||
!pythonRuntimeCopied || !pythonProbeWritten || pythonRunResult != 0 ||
!pythonVersionVisible ||
!curlCopied || curlVersionResult != 0 || curlNetworkResult == 0) return 20;
return 0;
}
@@ -11,6 +11,7 @@ $outputDir = Join-Path $env:TEMP ("SovereignAI-AppContainer-" + [guid]::NewGuid(
New-Item -ItemType Directory -Path $outputDir | Out-Null
$exe = Join-Path $outputDir 'appcontainer_probe.exe'
$obj = Join-Path $outputDir 'appcontainer_probe.obj'
$previousPythonHome = $env:SOVEREIGNAI_PYTHON_HOME
try {
Push-Location $repoRoot
@@ -21,6 +22,11 @@ try {
throw "C++ probe compilation failed with exit code $LASTEXITCODE"
}
$pythonHome = (& python -c 'import sys; print(sys.base_prefix)').Trim()
if ($LASTEXITCODE -ne 0 -or -not (Test-Path -LiteralPath $pythonHome -PathType Container)) {
throw 'Could not locate the active Python runtime to test isolated Python execution.'
}
$env:SOVEREIGNAI_PYTHON_HOME = $pythonHome
& $exe
$probeExit = $LASTEXITCODE
if ($probeExit -ne 0) {
@@ -30,6 +36,11 @@ try {
Pop-Location
}
} finally {
if ($null -eq $previousPythonHome) {
Remove-Item Env:SOVEREIGNAI_PYTHON_HOME -ErrorAction SilentlyContinue
} else {
$env:SOVEREIGNAI_PYTHON_HOME = $previousPythonHome
}
$resolvedOutput = (Resolve-Path -LiteralPath $outputDir -ErrorAction SilentlyContinue).Path
$tempRoot = [IO.Path]::GetFullPath($env:TEMP).TrimEnd('\') + '\'
if ($resolvedOutput -and $resolvedOutput.StartsWith($tempRoot, [StringComparison]::OrdinalIgnoreCase) -and