From 09d165843f1bb5b241f0df8f18a229ab16cfc6be Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Tue, 1 Oct 2024 12:08:59 +0200 Subject: [PATCH] VirtualMachine: add workaround cvars for not disabling platform qualification on arm64 or FreeBSD --- src/engine/framework/VirtualMachine.cpp | 91 ++++++++++++++++++------- 1 file changed, 68 insertions(+), 23 deletions(-) diff --git a/src/engine/framework/VirtualMachine.cpp b/src/engine/framework/VirtualMachine.cpp index 869c892e40..29893fb68f 100644 --- a/src/engine/framework/VirtualMachine.cpp +++ b/src/engine/framework/VirtualMachine.cpp @@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "qcommon/qcommon.h" #include "qcommon/sys.h" #include "VirtualMachine.h" +#include "CvarSystem.h" #ifdef _WIN32 #include @@ -44,6 +45,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #ifdef __linux__ #include +#if defined(DAEMON_ARCH_armhf) +#include +#endif #endif #endif @@ -55,6 +59,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x2000 #endif +static Cvar::Cvar workaround_naclArchitecture_arm64_disableQualification( + "workaround.naclArchitecture.arm64.disableQualification", + "Disable platform qualification when running armhf NaCl loader on arm64 Linux", + Cvar::NONE, true ); + +static Cvar::Cvar workaround_naclSystem_freebsd_disableQualification( + "workaround.naclSystem.freebsd.disableQualification", + "Disable platform qualification when running Linux NaCl loader on FreeBSD through Linuxulator", + Cvar::NONE, true ); + namespace VM { // https://github.com/Unvanquished/Unvanquished/issues/944#issuecomment-744454772 @@ -199,6 +213,9 @@ static std::pair InternalLoadModule(std::pair CreateNaClVM(std::pair pair, Str::StringRef name, bool debug, bool extract, int debugLoader) { + Cvar::Latch( workaround_naclArchitecture_arm64_disableQualification ); + Cvar::Latch( workaround_naclSystem_freebsd_disableQualification ); + CheckMinAddressSysctlTooLarge(); const std::string& libPath = FS::GetLibPath(); #ifdef NACL_RUNTIME_PATH @@ -258,42 +275,70 @@ static std::pair CreateNaClVM(std::pair Error while loading "sgame-armhf.nexe": CPU model is not supported - PLATFORM QUALIFICATION DISABLED BY -Q - Native Client's sandbox will be unreliable! + From nacl_loader --help we can read: - But the nexe will load and run. */ + > -Q disable platform qualification (dangerous!) - args.push_back("-Q"); - #endif -#else - Q_UNUSED(bootstrap); - args.push_back(nacl_loader.c_str()); + When this option is enabled, nacl_loader will print: - #if defined(__FreeBSD__) - /* While it is possible to build a native FreeBSD engine, the only available NaCl loader - is the Linux one, which can run on Linuxulator (the FreeBSD Linux compatibility layer). - The Linux NaCl loader binary fails to qualify the platform and aborts with this message: + > PLATFORM QUALIFICATION DISABLED BY -Q - Native Client's sandbox will be unreliable! - Bus error (core dumped) + But the nexe will load and run. */ - The Linux NaCl loader runs properly on Linuxulator when we disable the qualification. - It also works without nacl_helper_bootstrap. */ + if ( onArm64 && workaround_naclArchitecture_arm64_disableQualification.Get() ) + { + Log::Warn("Disabling NaCL platform qualification on arm64 kernel architecture"); + disableQualification = true; + } +#endif - args.push_back("-Q"); - #endif +#if defined(__FreeBSD__) + /* While it is possible to build a native FreeBSD engine, the only available NaCl loader + is the Linux one, which can run on Linuxulator (the FreeBSD Linux compatibility layer). + + The Linux NaCl loader binary fails to qualify the platform and aborts with this message: + + > Bus error (core dumped) + + The Linux NaCl loader runs properly on Linuxulator when we disable the qualification. */ + + if (workaround_naclSystem_freebsd_disableQualification.Get()) + { + Log::Warn("Disabling NaCL platform qualification on FreeBSD system"); + disableQualification = true; + } #endif + + if (disableQualification) + { + args.push_back("-Q"); + } + if (debug) { args.push_back("-g"); }