From 50d0f59597267ba9e48b5aa7360e7bf3ced9e6ee Mon Sep 17 00:00:00 2001 From: slipher Date: Thu, 30 Jul 2026 10:16:01 -0500 Subject: [PATCH 1/6] Refactor: function for Linux arm64 check for VM --- src/engine/framework/VirtualMachine.cpp | 31 ++++++++++++++----------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/engine/framework/VirtualMachine.cpp b/src/engine/framework/VirtualMachine.cpp index df2739b9f3..6c85776dbc 100644 --- a/src/engine/framework/VirtualMachine.cpp +++ b/src/engine/framework/VirtualMachine.cpp @@ -177,6 +177,22 @@ static void CheckMinAddressSysctlTooLarge() #endif // __linux__ } +#if defined(__linux__) && (defined(YOKAI_ARCH_ARM64) || defined(YOKAI_ARCH_ARMHF)) +static bool OnArm64() +{ +#if defined(YOKAI_ARCH_ARM64) + bool onArm64 = true; +#elif defined(YOKAI_ARCH_ARMHF) + bool onArm64 = false; + struct utsname buf; + if (!uname(&buf)) { + onArm64 = !strcmp(buf.machine, "aarch64"); + } +#endif + return onArm64; +} +#endif + // Platform-specific code to load a module static std::pair InternalLoadModule(std::pair pair, const char* const* args, bool reserve_mem, FS::File stderrRedirect = FS::File(), bool inheritEnvironment = false) { @@ -423,17 +439,6 @@ static std::pair CreateNaClVM(std::pair CreateNaClVM(std::pair Date: Thu, 30 Jul 2026 11:28:20 -0500 Subject: [PATCH 2/6] Get rid of nacl_helper_bootstrap-armhf executable Set up the chdir and environment variable in posix_spawn. Fixes #1336. --- CMakeLists.txt | 3 - src/engine/framework/VirtualMachine.cpp | 17 +++-- .../nacl_helper_bootstrap-armhf.cpp | 62 ------------------- 3 files changed, 11 insertions(+), 71 deletions(-) delete mode 100644 tools/nacl_helper_bootstrap-armhf/nacl_helper_bootstrap-armhf.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 65ff1a430b..7342f61ee5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -985,9 +985,6 @@ if (DEPS_DIR AND HAS_NACL AND (BUILD_CLIENT OR BUILD_TTY_CLIENT OR BUILD_SERVER # Linux uses a bootstrap program to reserve address space if (YOKAI_TARGET_SYSTEM_LINUX_COMPATIBILITY) if (YOKAI_TARGET_ARCH_ARM64) - add_executable(nacl_helper_bootstrap-armhf tools/nacl_helper_bootstrap-armhf/nacl_helper_bootstrap-armhf.cpp) - add_dependencies(runtime_deps nacl_helper_bootstrap-armhf) - add_custom_command(TARGET runtime_deps PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${FULL_OUTPUT_DIR}/lib-armhf diff --git a/src/engine/framework/VirtualMachine.cpp b/src/engine/framework/VirtualMachine.cpp index 6c85776dbc..e60332c037 100644 --- a/src/engine/framework/VirtualMachine.cpp +++ b/src/engine/framework/VirtualMachine.cpp @@ -299,13 +299,22 @@ static std::pair InternalLoadModule(std::pair("LD_LIBRARY_PATH=lib-armhf"); + if (0 != posix_spawn_file_actions_addchdir_np(&fileActions, FS::GetLibPath().c_str())) { + Sys::Error("failed posix_spawn_file_actions_addchdir"); + } + } +#endif + // By default, the child process gets an empty environment for sandboxing. // When Box64 emulation is used, the child needs to inherit the parent's // environment so Box64 can find its configuration (e.g. ~/.box64rc, HOME) // and honor settings like BOX64_DYNAREC_PERFMAP. - char* emptyEnv[] = {nullptr}; char** envp = inheritEnvironment ? environ : emptyEnv; + pid_t pid; int err = posix_spawn(&pid, args[0], &fileActions, nullptr, const_cast(args), envp); posix_spawn_file_actions_destroy(&fileActions); if (err != 0) { @@ -410,11 +419,7 @@ static std::pair CreateNaClVM(std::pair -#include -#include -#include -#include -#include - -int main(int argc, char *argv[]) { - char *directory = dirname(strdup(argv[0])); - - int err = chdir(directory); - - if (err != 0) { - return err; - } - - err = putenv(strdup("LD_LIBRARY_PATH=lib-armhf")); - - if (err != 0) { - return err; - } - - char *helper = strdup("./nacl_helper_bootstrap"); - argv[0] = helper; - - execv(helper, argv); - - // The execv() function returns only if an error has occurred. - printf("nacl_helper_bootstrap-armhf: %s\n", strerror(errno)); - - return 1; -} From ef790944bae02edbb2e2377bb7b5189f373b3386 Mon Sep 17 00:00:00 2001 From: slipher Date: Mon, 7 Sep 2026 01:53:26 -0500 Subject: [PATCH 3/6] Make the box64 inherit environment thing less confusing When box64 is used for the NaCl loader, environment variables are allowed to pass through. Make it clearer that this is the bool argument being passed and avoid unnecessary ifdef. --- src/engine/framework/VirtualMachine.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/engine/framework/VirtualMachine.cpp b/src/engine/framework/VirtualMachine.cpp index e60332c037..099ee0abd0 100644 --- a/src/engine/framework/VirtualMachine.cpp +++ b/src/engine/framework/VirtualMachine.cpp @@ -337,9 +337,9 @@ static std::pair CreateNaClVM(std::pair CreateNaClVM(std::pair CreateNaClVM(std::pair CreateNativeVM(std::pair pair, Str::StringRef name, bool debug) { From efb8fa9389423648bd4a44eabb39b708097d26b2 Mon Sep 17 00:00:00 2001 From: slipher Date: Mon, 7 Sep 2026 01:53:26 -0500 Subject: [PATCH 4/6] Don't use nacl_helper_bootstrap with x86-64 loader Remove cvars controlling whether the Linux bootstrap loader is used. Never use bootstrap with the amd64 loader. Always use bootstrap with 32-bit loaders. Remove amd64 bootstrap usage from deps. Closes https://github.com/DaemonEngine/Daemon/issues/1327. --- CMakeLists.txt | 14 ++++--- external_deps/build.sh | 1 - src/engine/framework/VirtualMachine.cpp | 53 +++++-------------------- 3 files changed, 19 insertions(+), 49 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7342f61ee5..a60cb0f54c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -982,7 +982,7 @@ if (DEPS_DIR AND HAS_NACL AND (BUILD_CLIENT OR BUILD_TTY_CLIENT OR BUILD_SERVER ${FULL_OUTPUT_DIR}/irt_core-${DAEMON_NACL_ARCH_NAME}.nexe ) - # Linux uses a bootstrap program to reserve address space + # Linux uses a bootstrap program to reserve address space for 32-bit runtimes if (YOKAI_TARGET_SYSTEM_LINUX_COMPATIBILITY) if (YOKAI_TARGET_ARCH_ARM64) add_custom_command(TARGET runtime_deps PRE_BUILD @@ -997,11 +997,13 @@ if (DEPS_DIR AND HAS_NACL AND (BUILD_CLIENT OR BUILD_TTY_CLIENT OR BUILD_SERVER ) endif() - add_custom_command(TARGET runtime_deps PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${DEPS_DIR}/nacl_helper_bootstrap - ${FULL_OUTPUT_DIR}/nacl_helper_bootstrap - ) + if (YOKAI_TARGET_ARCH_I686 OR YOKAI_TARGET_ARCH_ARMHF OR YOKAI_TARGET_ARCH_ARM64) + add_custom_command(TARGET runtime_deps PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${DEPS_DIR}/nacl_helper_bootstrap + ${FULL_OUTPUT_DIR}/nacl_helper_bootstrap + ) + endif() endif() # Win32 requires nacl_loader_amd64.exe in order to run on Win64 diff --git a/external_deps/build.sh b/external_deps/build.sh index 2c9c61aa9a..528278a6cc 100755 --- a/external_deps/build.sh +++ b/external_deps/build.sh @@ -1111,7 +1111,6 @@ build_naclruntime() { cd "${dir_name}" env -i /usr/bin/env bash -l -c "python3 /usr/bin/scons --mode=opt-linux 'platform=${NACL_ARCH}' werror=0 sysinfo=0 sel_ldr" - smart_copy "scons-out/opt-linux-${NACL_ARCH}/staging/nacl_helper_bootstrap" "${PREFIX}/nacl_helper_bootstrap" smart_copy "scons-out/opt-linux-${NACL_ARCH}/staging/sel_ldr" "${PREFIX}/nacl_loader" } diff --git a/src/engine/framework/VirtualMachine.cpp b/src/engine/framework/VirtualMachine.cpp index 099ee0abd0..a6ede7c4cf 100644 --- a/src/engine/framework/VirtualMachine.cpp +++ b/src/engine/framework/VirtualMachine.cpp @@ -81,11 +81,6 @@ static Cvar::Cvar workaround_box64_disableQualification( "Disable platform qualification when running amd64 NaCl loader under Box64 emulation", Cvar::NONE, true); -static Cvar::Cvar workaround_box64_disableBootstrap( - "workaround.box64.disableBootstrap", - "Disable NaCl bootstrap helper when using Box64 emulation", - Cvar::NONE, true); - static Cvar::Cvar vm_box64_path( "vm.box64.path", "Path to the box64 binary for NaCl emulation (empty = search PATH)", @@ -128,11 +123,6 @@ static Cvar::Cvar vm_nacl_qualification( "Enable NaCl loader platform qualification", Cvar::INIT, true); -static Cvar::Cvar vm_nacl_bootstrap( - "vm.nacl.bootstrap", - "Use NaCl bootstrap helper", - Cvar::INIT, true); - static Cvar::Cvar vm_timeout( "vm.timeout", "Receive timeout in seconds", @@ -390,50 +380,29 @@ static std::pair CreateNaClVM(std::pair Date: Mon, 7 Sep 2026 03:10:10 -0500 Subject: [PATCH 5/6] Windows: block NaCl process from inheriting environment When creating a NaCl (or native exe) VM on Windows, block evironment variables from being passed through to the subprocess as is done on *nix. Probably we do this since there are NACL* variables that can disable secure sandboxing. inheritEnvironment is always false on Windows, but I implemented the true case anyway since it's less code than having the Q_UNUSED and asserting it's false. --- src/engine/framework/VirtualMachine.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/engine/framework/VirtualMachine.cpp b/src/engine/framework/VirtualMachine.cpp index a6ede7c4cf..9114c919ec 100644 --- a/src/engine/framework/VirtualMachine.cpp +++ b/src/engine/framework/VirtualMachine.cpp @@ -248,8 +248,12 @@ static std::pair InternalLoadModule(std::pair InternalLoadModule(std::pair Date: Tue, 15 Sep 2026 06:45:37 -0500 Subject: [PATCH 6/6] Check mmap_min_addr only if using NaCl bootstrap Check the Linux sysctl vm.mmap_min_addr only when using the NaCl bootstrap (rather than always when using NaCl). Or equivalently, check it only with 32-bit NaCl runtimes. The bootstrap fails to start when the value is too high to due low fixed address mappings. On ARM at least, sel_ldr proper would also fail with a too-high min address since that disturbs the address space layout. On 64-bit there is neither the bootstrap nor 0-based address space layout so it always works. --- src/engine/framework/VirtualMachine.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/engine/framework/VirtualMachine.cpp b/src/engine/framework/VirtualMachine.cpp index 9114c919ec..619f25ec1b 100644 --- a/src/engine/framework/VirtualMachine.cpp +++ b/src/engine/framework/VirtualMachine.cpp @@ -319,7 +319,6 @@ static std::pair InternalLoadModule(std::pair CreateNaClVM(std::pair pair, Str::StringRef name, bool debug, bool extract, int debugLoader) { - CheckMinAddressSysctlTooLarge(); const std::string& libPath = FS::GetLibPath(); #ifdef DAEMON_NACL_RUNTIME_PATH const char* naclPath = DAEMON_NACL_RUNTIME_PATH_STRING; @@ -395,6 +394,7 @@ static std::pair CreateNaClVM(std::pair CreateNaClVM(std::pair