diff --git a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp --- a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp +++ b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp @@ -325,30 +325,84 @@ policy->AddDynamic(perms, trimPath.get()); } } } +static void AddX11Dependencies(SandboxBroker::Policy* policy) { + // Allow Primus to contact the Bumblebee daemon to manage GPU + // switching on NVIDIA Optimus systems. + const char* bumblebeeSocket = PR_GetEnv("BUMBLEBEE_SOCKET"); + if (bumblebeeSocket == nullptr) { + bumblebeeSocket = "/var/run/bumblebee.socket"; + } + policy->AddPath(SandboxBroker::MAY_CONNECT, bumblebeeSocket); + +#if defined(MOZ_WIDGET_GTK) && defined(MOZ_X11) + // Allow local X11 connections, for several purposes: + // + // * for content processes to use WebGL when the browser is in headless + // mode, by opening the X display if/when needed + // + // * if Primus or VirtualGL is used, to contact the secondary X server + static const bool kIsX11 = + !mozilla::widget::GdkIsWaylandDisplay() && PR_GetEnv("DISPLAY"); + if (kIsX11) { + policy->AddPrefix(SandboxBroker::MAY_CONNECT, "/tmp/.X11-unix/X"); + if (auto* const xauth = PR_GetEnv("XAUTHORITY")) { + policy->AddPath(rdonly, xauth); + } else if (auto* const home = PR_GetEnv("HOME")) { + // This follows the logic in libXau: append "/.Xauthority", + // even if $HOME ends in a slash, except in the special case + // where HOME=/ because POSIX allows implementations to treat + // an initial double slash specially. + nsAutoCString xauth(home); + if (xauth != "/"_ns) { + xauth.Append('/'); + } + xauth.AppendLiteral(".Xauthority"); + policy->AddPath(rdonly, xauth.get()); + } + } +#endif +} + +static void AddGLDependencies(SandboxBroker::Policy* policy) { + // Devices + policy->AddDir(rdwr, "/dev/dri"); + policy->AddFilePrefix(rdwr, "/dev", "nvidia"); + + // Hardware info + AddDriPaths(policy); + + // /etc and /usr/share (glvnd, libdrm, drirc, ...?) + policy->AddDir(rdonly, "/etc"); + policy->AddDir(rdonly, "/usr/share"); + policy->AddDir(rdonly, "/usr/local/share"); + + // Note: This function doesn't do anything about Mesa's shader + // cache, because the details can vary by process type, including + // whether caching is enabled. + + AddX11Dependencies(policy); +} + void SandboxBrokerPolicyFactory::InitContentPolicy() { const bool headless = StaticPrefs::security_sandbox_content_headless_AtStartup(); // Policy entries that are the same in every process go here, and // are cached over the lifetime of the factory. SandboxBroker::Policy* policy = new SandboxBroker::Policy; // Write permssions - // - if (!headless) { - // Bug 1308851: NVIDIA proprietary driver when using WebGL - policy->AddFilePrefix(rdwr, "/dev", "nvidia"); - - // Bug 1312678: Mesa with DRI when using WebGL - policy->AddDir(rdwr, "/dev/dri"); - } // Bug 1575985: WASM library sandbox needs RW access to /dev/null policy->AddPath(rdwr, "/dev/null"); + if (!headless) { + AddGLDependencies(policy); + } + // Read permissions policy->AddPath(rdonly, "/dev/urandom"); policy->AddPath(rdonly, "/dev/random"); policy->AddPath(rdonly, "/proc/sys/crypto/fips_enabled"); policy->AddPath(rdonly, "/proc/cpuinfo"); @@ -370,13 +424,10 @@ policy->AddDir(rdonly, "/run/host/fonts"); policy->AddDir(rdonly, "/run/host/user-fonts"); policy->AddDir(rdonly, "/run/host/local-fonts"); policy->AddDir(rdonly, "/var/cache/fontconfig"); - if (!headless) { - AddDriPaths(policy); - } AddLdconfigPaths(policy); AddLdLibraryEnvPaths(policy); if (!headless) { // Bug 1385715: NVIDIA PRIME support @@ -569,45 +620,11 @@ } } #endif if (!headless) { - // Allow Primus to contact the Bumblebee daemon to manage GPU - // switching on NVIDIA Optimus systems. - const char* bumblebeeSocket = PR_GetEnv("BUMBLEBEE_SOCKET"); - if (bumblebeeSocket == nullptr) { - bumblebeeSocket = "/var/run/bumblebee.socket"; - } - policy->AddPath(SandboxBroker::MAY_CONNECT, bumblebeeSocket); - -#if defined(MOZ_WIDGET_GTK) && defined(MOZ_X11) - // Allow local X11 connections, for several purposes: - // - // * for content processes to use WebGL when the browser is in headless - // mode, by opening the X display if/when needed - // - // * if Primus or VirtualGL is used, to contact the secondary X server - static const bool kIsX11 = - !mozilla::widget::GdkIsWaylandDisplay() && PR_GetEnv("DISPLAY"); - if (kIsX11) { - policy->AddPrefix(SandboxBroker::MAY_CONNECT, "/tmp/.X11-unix/X"); - if (auto* const xauth = PR_GetEnv("XAUTHORITY")) { - policy->AddPath(rdonly, xauth); - } else if (auto* const home = PR_GetEnv("HOME")) { - // This follows the logic in libXau: append "/.Xauthority", - // even if $HOME ends in a slash, except in the special case - // where HOME=/ because POSIX allows implementations to treat - // an initial double slash specially. - nsAutoCString xauth(home); - if (xauth != "/"_ns) { - xauth.Append('/'); - } - xauth.AppendLiteral(".Xauthority"); - policy->AddPath(rdonly, xauth.get()); - } - } -#endif + AddX11Dependencies(policy); } // Bug 1732580: when packaged as a strictly confined snap, may need // read-access to configuration files under $SNAP/. const char* snap = PR_GetEnv("SNAP");