Skip to content

Commit

Permalink
VirtualMachine: add workaround cvars for not disabling platform quali…
Browse files Browse the repository at this point in the history
…fication on arm64 or FreeBSD
  • Loading branch information
illwieckz committed Oct 1, 2024
1 parent 4108131 commit 09d1658
Showing 1 changed file with 68 additions and 23 deletions.
91 changes: 68 additions & 23 deletions src/engine/framework/VirtualMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <windows.h>
Expand All @@ -44,6 +45,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sys/wait.h>
#ifdef __linux__
#include <sys/prctl.h>
#if defined(DAEMON_ARCH_armhf)
#include <sys/utsname.h>
#endif
#endif
#endif

Expand All @@ -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<bool> 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<bool> 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
Expand Down Expand Up @@ -199,6 +213,9 @@ static std::pair<Sys::OSHandle, IPC::Socket> InternalLoadModule(std::pair<IPC::S
}

static std::pair<Sys::OSHandle, IPC::Socket> CreateNaClVM(std::pair<IPC::Socket, IPC::Socket> 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
Expand Down Expand Up @@ -258,42 +275,70 @@ static std::pair<Sys::OSHandle, IPC::Socket> CreateNaClVM(std::pair<IPC::Socket,
args.push_back(nacl_loader.c_str());
args.push_back("--r_debug=0xXXXXXXXXXXXXXXXX");
args.push_back("--reserved_at_zero=0xXXXXXXXXXXXXXXXX");
#else
Q_UNUSED(bootstrap);
args.push_back(nacl_loader.c_str());
#endif

#if defined(DAEMON_ARCH_arm64) || defined(DAEMON_ARCH_armhf)
/* This is required to run on Raspberry Pi 4,
otherwise nexe loading fails with this message:
bool disableQualification = false;

Error while loading "sgame-armhf.nexe": CPU model is not supported
#if defined(DAEMON_ARCH_arm64) || defined(DAEMON_ARCH_armhf)
#if defined(DAEMON_ARCH_arm64)
bool onArm64 = true;
#elif defined(DAEMON_ARCH_armhf)
bool onArm64 = false;

From nacl_loader --help we can read:
struct utsname buf;
if ( !uname( &buf ) )
{
onArm64 = !strcmp( buf.machine, "aarch64" );
}
#endif

-Q disable platform qualification (dangerous!)
/* This is required to run armhf NaCl loader on arm64 kernel
otherwise nexe loading fails with this message:
When this option is enabled, nacl_loader will print:
> 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");
}
Expand Down

0 comments on commit 09d1658

Please sign in to comment.