Updated to 101.0.1, More VA-API sandbox fixes (mzbz#1769182)

This commit is contained in:
Martin Stransky 2022-06-09 11:14:27 +02:00
parent 61879d2c53
commit fc1bf47cd8
9 changed files with 874 additions and 4 deletions

2
.gitignore vendored
View File

@ -513,3 +513,5 @@ firefox-3.6.4.source.tar.bz2
/firefox-langpacks-100.0.2-20220520.tar.xz
/firefox-101.0.source.tar.xz
/firefox-langpacks-101.0-20220530.tar.xz
/firefox-101.0.1.source.tar.xz
/firefox-langpacks-101.0.1-20220609.tar.xz

94
D146271.diff Normal file
View File

@ -0,0 +1,94 @@
diff -up firefox-101.0/security/sandbox/linux/SandboxFilter.cpp.D146271.diff firefox-101.0/security/sandbox/linux/SandboxFilter.cpp
--- firefox-101.0/security/sandbox/linux/SandboxFilter.cpp.D146271.diff 2022-05-27 01:16:59.000000000 +0200
+++ firefox-101.0/security/sandbox/linux/SandboxFilter.cpp 2022-06-09 09:59:35.569235176 +0200
@@ -125,28 +125,12 @@ namespace mozilla {
// denied if no broker client is provided by the concrete class.
class SandboxPolicyCommon : public SandboxPolicyBase {
protected:
- enum class ShmemUsage : uint8_t {
- MAY_CREATE,
- ONLY_USE,
- };
-
- enum class AllowUnsafeSocketPair : uint8_t {
- NO,
- YES,
- };
-
+ // Subclasses can assign these in their constructors to loosen the
+ // default settings.
SandboxBrokerClient* mBroker = nullptr;
bool mMayCreateShmem = false;
bool mAllowUnsafeSocketPair = false;
- explicit SandboxPolicyCommon(SandboxBrokerClient* aBroker,
- ShmemUsage aShmemUsage,
- AllowUnsafeSocketPair aAllowUnsafeSocketPair)
- : mBroker(aBroker),
- mMayCreateShmem(aShmemUsage == ShmemUsage::MAY_CREATE),
- mAllowUnsafeSocketPair(aAllowUnsafeSocketPair ==
- AllowUnsafeSocketPair::YES) {}
-
SandboxPolicyCommon() = default;
typedef const sandbox::arch_seccomp_data& ArgsRef;
@@ -1228,11 +1212,13 @@ class ContentSandboxPolicy : public Sand
public:
ContentSandboxPolicy(SandboxBrokerClient* aBroker,
ContentProcessSandboxParams&& aParams)
- : SandboxPolicyCommon(aBroker, ShmemUsage::MAY_CREATE,
- AllowUnsafeSocketPair::YES),
- mParams(std::move(aParams)),
+ : mParams(std::move(aParams)),
mAllowSysV(PR_GetEnv("MOZ_SANDBOX_ALLOW_SYSV") != nullptr),
- mUsingRenderDoc(PR_GetEnv("RENDERDOC_CAPTUREOPTS") != nullptr) {}
+ mUsingRenderDoc(PR_GetEnv("RENDERDOC_CAPTUREOPTS") != nullptr) {
+ mBroker = aBroker;
+ mMayCreateShmem = true;
+ mAllowUnsafeSocketPair = true;
+ }
~ContentSandboxPolicy() override = default;
@@ -1762,9 +1748,10 @@ UniquePtr<sandbox::bpf_dsl::Policy> GetM
// segments, so it may need file brokering.
class RDDSandboxPolicy final : public SandboxPolicyCommon {
public:
- explicit RDDSandboxPolicy(SandboxBrokerClient* aBroker)
- : SandboxPolicyCommon(aBroker, ShmemUsage::MAY_CREATE,
- AllowUnsafeSocketPair::NO) {}
+ explicit RDDSandboxPolicy(SandboxBrokerClient* aBroker) {
+ mBroker = aBroker;
+ mMayCreateShmem = true;
+ }
#ifndef ANDROID
Maybe<ResultExpr> EvaluateIpcCall(int aCall, int aArgShift) const override {
@@ -1875,9 +1862,10 @@ UniquePtr<sandbox::bpf_dsl::Policy> GetD
// the SocketProcess sandbox looks like.
class SocketProcessSandboxPolicy final : public SandboxPolicyCommon {
public:
- explicit SocketProcessSandboxPolicy(SandboxBrokerClient* aBroker)
- : SandboxPolicyCommon(aBroker, ShmemUsage::MAY_CREATE,
- AllowUnsafeSocketPair::NO) {}
+ explicit SocketProcessSandboxPolicy(SandboxBrokerClient* aBroker) {
+ mBroker = aBroker;
+ mMayCreateShmem = true;
+ }
static intptr_t FcntlTrap(const sandbox::arch_seccomp_data& aArgs,
void* aux) {
@@ -2013,9 +2001,10 @@ UniquePtr<sandbox::bpf_dsl::Policy> GetS
class UtilitySandboxPolicy : public SandboxPolicyCommon {
public:
- explicit UtilitySandboxPolicy(SandboxBrokerClient* aBroker)
- : SandboxPolicyCommon(aBroker, ShmemUsage::MAY_CREATE,
- AllowUnsafeSocketPair::NO) {}
+ explicit UtilitySandboxPolicy(SandboxBrokerClient* aBroker) {
+ mBroker = aBroker;
+ mMayCreateShmem = true;
+ }
ResultExpr PrctlPolicy() const override {
Arg<int> op(0);

373
D146272.diff Normal file
View File

@ -0,0 +1,373 @@
diff --git a/security/sandbox/linux/SandboxFilter.cpp b/security/sandbox/linux/SandboxFilter.cpp
--- a/security/sandbox/linux/SandboxFilter.cpp
+++ b/security/sandbox/linux/SandboxFilter.cpp
@@ -128,10 +128,11 @@
// Subclasses can assign these in their constructors to loosen the
// default settings.
SandboxBrokerClient* mBroker = nullptr;
bool mMayCreateShmem = false;
bool mAllowUnsafeSocketPair = false;
+ bool mBrokeredConnect = false; // Can connect() be brokered?
SandboxPolicyCommon() = default;
typedef const sandbox::arch_seccomp_data& ArgsRef;
@@ -533,10 +534,124 @@
MOZ_CRASH("unreachable?");
return -ENOSYS;
#endif
}
+ // This just needs to return something to stand in for the
+ // unconnected socket until ConnectTrap, below, and keep track of
+ // the socket type somehow. Half a socketpair *is* a socket, so it
+ // should result in minimal confusion in the caller.
+ static intptr_t FakeSocketTrapCommon(int domain, int type, int protocol) {
+ int fds[2];
+ // X11 client libs will still try to getaddrinfo() even for a
+ // local connection. Also, WebRTC still has vestigial network
+ // code trying to do things in the content process. Politely tell
+ // them no.
+ if (domain != AF_UNIX) {
+ return -EAFNOSUPPORT;
+ }
+ if (socketpair(domain, type, protocol, fds) != 0) {
+ return -errno;
+ }
+ close(fds[1]);
+ return fds[0];
+ }
+
+ static intptr_t FakeSocketTrap(ArgsRef aArgs, void* aux) {
+ return FakeSocketTrapCommon(static_cast<int>(aArgs.args[0]),
+ static_cast<int>(aArgs.args[1]),
+ static_cast<int>(aArgs.args[2]));
+ }
+
+ static intptr_t FakeSocketTrapLegacy(ArgsRef aArgs, void* aux) {
+ const auto innerArgs = reinterpret_cast<unsigned long*>(aArgs.args[1]);
+
+ return FakeSocketTrapCommon(static_cast<int>(innerArgs[0]),
+ static_cast<int>(innerArgs[1]),
+ static_cast<int>(innerArgs[2]));
+ }
+
+ static Maybe<int> DoGetSockOpt(int fd, int optname) {
+ int optval;
+ socklen_t optlen = sizeof(optval);
+
+ if (getsockopt(fd, SOL_SOCKET, optname, &optval, &optlen) != 0) {
+ return Nothing();
+ }
+ MOZ_RELEASE_ASSERT(static_cast<size_t>(optlen) == sizeof(optval));
+ return Some(optval);
+ }
+
+ // Substitute the newly connected socket from the broker for the
+ // original socket. This is meant to be used on a fd from
+ // FakeSocketTrap, above, but it should also work to simulate
+ // re-connect()ing a real connected socket.
+ //
+ // Warning: This isn't quite right if the socket is dup()ed, because
+ // other duplicates will still be the original socket, but hopefully
+ // nothing we're dealing with does that.
+ static intptr_t ConnectTrapCommon(SandboxBrokerClient* aBroker, int aFd,
+ const struct sockaddr_un* aAddr,
+ socklen_t aLen) {
+ if (aFd < 0) {
+ return -EBADF;
+ }
+ const auto maybeDomain = DoGetSockOpt(aFd, SO_DOMAIN);
+ if (!maybeDomain) {
+ return -errno;
+ }
+ if (*maybeDomain != AF_UNIX) {
+ return -EAFNOSUPPORT;
+ }
+ const auto maybeType = DoGetSockOpt(aFd, SO_TYPE);
+ if (!maybeType) {
+ return -errno;
+ }
+ const int oldFlags = fcntl(aFd, F_GETFL);
+ if (oldFlags == -1) {
+ return -errno;
+ }
+ const int newFd = aBroker->Connect(aAddr, aLen, *maybeType);
+ if (newFd < 0) {
+ return newFd;
+ }
+ // Copy over the nonblocking flag. The connect() won't be
+ // nonblocking in that case, but that shouldn't matter for
+ // AF_UNIX. The other fcntl-settable flags are either irrelevant
+ // for sockets (e.g., O_APPEND) or would be blocked by this
+ // seccomp-bpf policy, so they're ignored.
+ if (fcntl(newFd, F_SETFL, oldFlags & O_NONBLOCK) != 0) {
+ close(newFd);
+ return -errno;
+ }
+ if (dup2(newFd, aFd) < 0) {
+ close(newFd);
+ return -errno;
+ }
+ close(newFd);
+ return 0;
+ }
+
+ static intptr_t ConnectTrap(ArgsRef aArgs, void* aux) {
+ typedef const struct sockaddr_un* AddrPtr;
+
+ return ConnectTrapCommon(static_cast<SandboxBrokerClient*>(aux),
+ static_cast<int>(aArgs.args[0]),
+ reinterpret_cast<AddrPtr>(aArgs.args[1]),
+ static_cast<socklen_t>(aArgs.args[2]));
+ }
+
+ static intptr_t ConnectTrapLegacy(ArgsRef aArgs, void* aux) {
+ const auto innerArgs = reinterpret_cast<unsigned long*>(aArgs.args[1]);
+ typedef const struct sockaddr_un* AddrPtr;
+
+ return ConnectTrapCommon(static_cast<SandboxBrokerClient*>(aux),
+ static_cast<int>(innerArgs[0]),
+ reinterpret_cast<AddrPtr>(innerArgs[1]),
+ static_cast<socklen_t>(innerArgs[2]));
+ }
+
public:
ResultExpr InvalidSyscall() const override {
return Trap(BlockedSyscallTrap, nullptr);
}
@@ -630,15 +745,37 @@
return Some(Allow());
}
Arg<int> level(1), optname(2);
// SO_SNDBUF is used by IPC to avoid constructing
// unnecessarily large gather arrays for `sendmsg`.
- return Some(
- If(AllOf(level == SOL_SOCKET, optname == SO_SNDBUF), Allow())
- .Else(InvalidSyscall()));
+ //
+ // SO_DOMAIN and SO_TYPE are needed for connect() brokering,
+ // but they're harmless even when it's not enabled.
+ return Some(If(AllOf(level == SOL_SOCKET,
+ AnyOf(optname == SO_SNDBUF, optname == SO_DOMAIN,
+ optname == SO_TYPE)),
+ Allow())
+ .Else(InvalidSyscall()));
}
+ // These two cases are for connect() brokering, if enabled.
+ case SYS_SOCKET:
+ if (mBrokeredConnect) {
+ const auto trapFn = aHasArgs ? FakeSocketTrap : FakeSocketTrapLegacy;
+ MOZ_ASSERT(mBroker);
+ return Some(Trap(trapFn, mBroker));
+ }
+ return Nothing();
+
+ case SYS_CONNECT:
+ if (mBrokeredConnect) {
+ const auto trapFn = aHasArgs ? ConnectTrap : ConnectTrapLegacy;
+ MOZ_ASSERT(mBroker);
+ return Some(Trap(trapFn, mBroker));
+ }
+ return Nothing();
+
default:
return Nothing();
}
}
@@ -1006,10 +1143,16 @@
return If(AnyOf(request == TCGETS, request == TIOCGWINSZ),
Error(ENOTTY))
.Else(SandboxPolicyBase::EvaluateSyscall(sysno));
}
+ CASES_FOR_dup2: // See ConnectTrapCommon
+ if (mBrokeredConnect) {
+ return Allow();
+ }
+ return SandboxPolicyBase::EvaluateSyscall(sysno);
+
#ifdef MOZ_ASAN
// ASAN's error reporter wants to know if stderr is a tty.
case __NR_ioctl: {
Arg<int> fd(0);
return If(fd == STDERR_FILENO, Error(ENOTTY)).Else(InvalidSyscall());
@@ -1093,133 +1236,20 @@
close(fd);
return rv;
}
- // This just needs to return something to stand in for the
- // unconnected socket until ConnectTrap, below, and keep track of
- // the socket type somehow. Half a socketpair *is* a socket, so it
- // should result in minimal confusion in the caller.
- static intptr_t FakeSocketTrapCommon(int domain, int type, int protocol) {
- int fds[2];
- // X11 client libs will still try to getaddrinfo() even for a
- // local connection. Also, WebRTC still has vestigial network
- // code trying to do things in the content process. Politely tell
- // them no.
- if (domain != AF_UNIX) {
- return -EAFNOSUPPORT;
- }
- if (socketpair(domain, type, protocol, fds) != 0) {
- return -errno;
- }
- close(fds[1]);
- return fds[0];
- }
-
- static intptr_t FakeSocketTrap(ArgsRef aArgs, void* aux) {
- return FakeSocketTrapCommon(static_cast<int>(aArgs.args[0]),
- static_cast<int>(aArgs.args[1]),
- static_cast<int>(aArgs.args[2]));
- }
-
- static intptr_t FakeSocketTrapLegacy(ArgsRef aArgs, void* aux) {
- const auto innerArgs = reinterpret_cast<unsigned long*>(aArgs.args[1]);
-
- return FakeSocketTrapCommon(static_cast<int>(innerArgs[0]),
- static_cast<int>(innerArgs[1]),
- static_cast<int>(innerArgs[2]));
- }
-
- static Maybe<int> DoGetSockOpt(int fd, int optname) {
- int optval;
- socklen_t optlen = sizeof(optval);
-
- if (getsockopt(fd, SOL_SOCKET, optname, &optval, &optlen) != 0) {
- return Nothing();
- }
- MOZ_RELEASE_ASSERT(static_cast<size_t>(optlen) == sizeof(optval));
- return Some(optval);
- }
-
- // Substitute the newly connected socket from the broker for the
- // original socket. This is meant to be used on a fd from
- // FakeSocketTrap, above, but it should also work to simulate
- // re-connect()ing a real connected socket.
- //
- // Warning: This isn't quite right if the socket is dup()ed, because
- // other duplicates will still be the original socket, but hopefully
- // nothing we're dealing with does that.
- static intptr_t ConnectTrapCommon(SandboxBrokerClient* aBroker, int aFd,
- const struct sockaddr_un* aAddr,
- socklen_t aLen) {
- if (aFd < 0) {
- return -EBADF;
- }
- const auto maybeDomain = DoGetSockOpt(aFd, SO_DOMAIN);
- if (!maybeDomain) {
- return -errno;
- }
- if (*maybeDomain != AF_UNIX) {
- return -EAFNOSUPPORT;
- }
- const auto maybeType = DoGetSockOpt(aFd, SO_TYPE);
- if (!maybeType) {
- return -errno;
- }
- const int oldFlags = fcntl(aFd, F_GETFL);
- if (oldFlags == -1) {
- return -errno;
- }
- const int newFd = aBroker->Connect(aAddr, aLen, *maybeType);
- if (newFd < 0) {
- return newFd;
- }
- // Copy over the nonblocking flag. The connect() won't be
- // nonblocking in that case, but that shouldn't matter for
- // AF_UNIX. The other fcntl-settable flags are either irrelevant
- // for sockets (e.g., O_APPEND) or would be blocked by this
- // seccomp-bpf policy, so they're ignored.
- if (fcntl(newFd, F_SETFL, oldFlags & O_NONBLOCK) != 0) {
- close(newFd);
- return -errno;
- }
- if (dup2(newFd, aFd) < 0) {
- close(newFd);
- return -errno;
- }
- close(newFd);
- return 0;
- }
-
- static intptr_t ConnectTrap(ArgsRef aArgs, void* aux) {
- typedef const struct sockaddr_un* AddrPtr;
-
- return ConnectTrapCommon(static_cast<SandboxBrokerClient*>(aux),
- static_cast<int>(aArgs.args[0]),
- reinterpret_cast<AddrPtr>(aArgs.args[1]),
- static_cast<socklen_t>(aArgs.args[2]));
- }
-
- static intptr_t ConnectTrapLegacy(ArgsRef aArgs, void* aux) {
- const auto innerArgs = reinterpret_cast<unsigned long*>(aArgs.args[1]);
- typedef const struct sockaddr_un* AddrPtr;
-
- return ConnectTrapCommon(static_cast<SandboxBrokerClient*>(aux),
- static_cast<int>(innerArgs[0]),
- reinterpret_cast<AddrPtr>(innerArgs[1]),
- static_cast<socklen_t>(innerArgs[2]));
- }
-
public:
ContentSandboxPolicy(SandboxBrokerClient* aBroker,
ContentProcessSandboxParams&& aParams)
: mParams(std::move(aParams)),
mAllowSysV(PR_GetEnv("MOZ_SANDBOX_ALLOW_SYSV") != nullptr),
mUsingRenderDoc(PR_GetEnv("RENDERDOC_CAPTUREOPTS") != nullptr) {
mBroker = aBroker;
mMayCreateShmem = true;
mAllowUnsafeSocketPair = true;
+ mBrokeredConnect = true;
}
~ContentSandboxPolicy() override = default;
Maybe<ResultExpr> EvaluateSocketCall(int aCall,
@@ -1232,18 +1262,16 @@
#ifdef ANDROID
case SYS_SOCKET:
return Some(Error(EACCES));
#else // #ifdef DESKTOP
- case SYS_SOCKET: {
- const auto trapFn = aHasArgs ? FakeSocketTrap : FakeSocketTrapLegacy;
- return Some(AllowBelowLevel(4, Trap(trapFn, nullptr)));
- }
- case SYS_CONNECT: {
- const auto trapFn = aHasArgs ? ConnectTrap : ConnectTrapLegacy;
- return Some(AllowBelowLevel(4, Trap(trapFn, mBroker)));
- }
+ case SYS_SOCKET:
+ case SYS_CONNECT:
+ if (BelowLevel(4)) {
+ return Some(Allow());
+ }
+ return SandboxPolicyCommon::EvaluateSocketCall(aCall, aHasArgs);
case SYS_RECV:
case SYS_SEND:
case SYS_GETSOCKOPT:
case SYS_SETSOCKOPT:
case SYS_GETSOCKNAME:
@@ -1458,13 +1486,10 @@
case __NR_getrusage:
case __NR_times:
return Allow();
- CASES_FOR_dup2: // See ConnectTrapCommon
- return Allow();
-
case __NR_fsync:
case __NR_msync:
return Allow();
case __NR_getpriority:

90
D146273.diff Normal file
View File

@ -0,0 +1,90 @@
diff --git a/security/sandbox/linux/SandboxFilter.cpp b/security/sandbox/linux/SandboxFilter.cpp
--- a/security/sandbox/linux/SandboxFilter.cpp
+++ b/security/sandbox/linux/SandboxFilter.cpp
@@ -699,10 +699,18 @@
Maybe<ResultExpr> EvaluateSocketCall(int aCall,
bool aHasArgs) const override {
switch (aCall) {
case SYS_RECVMSG:
case SYS_SENDMSG:
+ // These next four aren't needed for IPC or other core
+ // functionality at the time of this writing, but they're
+ // subsets of recvmsg/sendmsg so there's nothing gained by not
+ // allowing them here (and simplifying subclasses).
+ case SYS_RECVFROM:
+ case SYS_SENDTO:
+ case SYS_RECV:
+ case SYS_SEND:
return Some(Allow());
case SYS_SOCKETPAIR: {
// We try to allow "safe" (always connected) socketpairs when using the
// file broker, or for content processes, but we may need to fall back
@@ -1253,12 +1261,10 @@
~ContentSandboxPolicy() override = default;
Maybe<ResultExpr> EvaluateSocketCall(int aCall,
bool aHasArgs) const override {
switch (aCall) {
- case SYS_RECVFROM:
- case SYS_SENDTO:
case SYS_SENDMMSG: // libresolv via libasyncns; see bug 1355274
return Some(Allow());
#ifdef ANDROID
case SYS_SOCKET:
@@ -1268,18 +1274,21 @@
case SYS_CONNECT:
if (BelowLevel(4)) {
return Some(Allow());
}
return SandboxPolicyCommon::EvaluateSocketCall(aCall, aHasArgs);
- case SYS_RECV:
- case SYS_SEND:
+
+ // FIXME (bug 1761134): sockopts should be filtered
case SYS_GETSOCKOPT:
case SYS_SETSOCKOPT:
+ // These next 3 were needed for X11; they may not be needed
+ // with X11 lockdown, but there's not much attack surface here.
case SYS_GETSOCKNAME:
case SYS_GETPEERNAME:
case SYS_SHUTDOWN:
return Some(Allow());
+
case SYS_ACCEPT:
case SYS_ACCEPT4:
if (mUsingRenderDoc) {
return Some(Allow());
}
@@ -1908,26 +1917,19 @@
}
Maybe<ResultExpr> EvaluateSocketCall(int aCall,
bool aHasArgs) const override {
switch (aCall) {
+ case SYS_SOCKET:
+ case SYS_CONNECT:
case SYS_BIND:
return Some(Allow());
- case SYS_SOCKET:
- return Some(Allow());
-
- case SYS_CONNECT:
- return Some(Allow());
-
- case SYS_RECVFROM:
- case SYS_SENDTO:
+ // FIXME(bug 1641401) do we really need this?
case SYS_SENDMMSG:
return Some(Allow());
- case SYS_RECV:
- case SYS_SEND:
case SYS_GETSOCKOPT:
case SYS_SETSOCKOPT:
case SYS_GETSOCKNAME:
case SYS_GETPEERNAME:
case SYS_SHUTDOWN:

158
D146274.diff Normal file
View File

@ -0,0 +1,158 @@
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");

125
D146275.diff Normal file
View File

@ -0,0 +1,125 @@
diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -418,10 +418,17 @@
nsresult rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR,
getter_AddRefs(contentTempDir));
if (NS_SUCCEEDED(rv)) {
contentTempDir->GetNativePath(mTmpDirName);
}
+ } else if (aProcessType == GeckoProcessType_RDD) {
+ // The RDD process makes limited use of EGL. If Mesa's shader
+ // cache is enabled and the directory isn't explicitly set, then
+ // it will try to getpwuid() the user which can cause problems
+ // with sandboxing. Because we shouldn't need shader caching in
+ // this process, we just disable the cache to prevent that.
+ mLaunchOptions->env_map["MESA_GLSL_CACHE_DISABLE"] = "true";
}
#endif
#if defined(MOZ_ENABLE_FORKSERVER)
if (aProcessType == GeckoProcessType_Content && ForkServiceChild::Get()) {
mLaunchOptions->use_forkserver = true;
diff --git a/security/sandbox/common/test/SandboxTestingChildTests.h b/security/sandbox/common/test/SandboxTestingChildTests.h
--- a/security/sandbox/common/test/SandboxTestingChildTests.h
+++ b/security/sandbox/common/test/SandboxTestingChildTests.h
@@ -21,14 +21,16 @@
# include <termios.h>
# include <sys/resource.h>
# include <sys/time.h>
# include <sys/utsname.h>
# include <sched.h>
+# include <sys/socket.h>
# include <sys/syscall.h>
# include <sys/un.h>
# include <linux/mempolicy.h>
# include "mozilla/ProcInfo_linux.h"
+# include "mozilla/UniquePtrExtensions.h"
# ifdef MOZ_X11
# include "X11/Xlib.h"
# include "X11UndefineNone.h"
# endif // MOZ_X11
# endif // XP_LINUX
@@ -595,12 +597,25 @@
return rv;
});
RunTestsSched(child);
- child->ErrnoTest("socket"_ns, false,
- [] { return socket(AF_UNIX, SOCK_STREAM, 0); });
+ child->ErrnoTest("socket_inet"_ns, false,
+ [] { return socket(AF_INET, SOCK_STREAM, 0); });
+
+ {
+ UniqueFileHandle fd(socket(AF_UNIX, SOCK_STREAM, 0));
+ child->ErrnoTest("socket_unix"_ns, true, [&] { return fd.get(); });
+
+ struct sockaddr_un sun {};
+ sun.sun_family = AF_UNIX;
+ strncpy(sun.sun_path, "/tmp/forbidden-sock", sizeof(sun.sun_path));
+
+ child->ErrnoValueTest("socket_unix_bind"_ns, ENOSYS, [&] {
+ return bind(fd.get(), (struct sockaddr*)&sun, sizeof(sun));
+ });
+ }
child->ErrnoTest("uname"_ns, true, [] {
struct utsname uts;
return uname(&uts);
});
diff --git a/security/sandbox/linux/SandboxFilter.cpp b/security/sandbox/linux/SandboxFilter.cpp
--- a/security/sandbox/linux/SandboxFilter.cpp
+++ b/security/sandbox/linux/SandboxFilter.cpp
@@ -1783,10 +1783,11 @@
class RDDSandboxPolicy final : public SandboxPolicyCommon {
public:
explicit RDDSandboxPolicy(SandboxBrokerClient* aBroker) {
mBroker = aBroker;
mMayCreateShmem = true;
+ mBrokeredConnect = true;
}
#ifndef ANDROID
Maybe<ResultExpr> EvaluateIpcCall(int aCall, int aArgShift) const override {
// The Intel media driver uses SysV IPC (semaphores and shared
@@ -1818,15 +1819,15 @@
#endif
Maybe<ResultExpr> EvaluateSocketCall(int aCall,
bool aHasArgs) const override {
switch (aCall) {
- // Mesa can call getpwuid_r to get the home dir, which can try
- // to connect to nscd (or maybe servers like NIS or LDAP); this
- // can't be safely allowed, but we can quietly deny it.
- case SYS_SOCKET:
- return Some(Error(EACCES));
+ // These are for X11.
+ case SYS_GETSOCKNAME:
+ case SYS_GETPEERNAME:
+ case SYS_SHUTDOWN:
+ return Some(Allow());
default:
return SandboxPolicyCommon::EvaluateSocketCall(aCall, aHasArgs);
}
}
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
@@ -853,13 +853,12 @@
if (developer_repo_dir) {
policy->AddDir(rdonly, developer_repo_dir);
}
}
- // VA-API needs DRI and GPU detection
- policy->AddDir(rdwr, "/dev/dri");
- AddDriPaths(policy.get());
+ // VA-API needs GPU access and GL context creation
+ AddGLDependencies(policy.get());
// FFmpeg and GPU drivers may need general-case library loading
AddLdconfigPaths(policy.get());
AddLdLibraryEnvPaths(policy.get());

View File

@ -162,8 +162,8 @@ ExcludeArch: aarch64
Summary: Mozilla Firefox Web browser
Name: firefox
Version: 101.0
Release: 2%{?pre_tag}%{?dist}
Version: 101.0.1
Release: 1%{?pre_tag}%{?dist}
URL: https://www.mozilla.org/firefox/
License: MPLv1.1 or GPLv2+ or LGPLv2+
Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}%{?pre_version}/source/firefox-%{version}%{?pre_version}.source.tar.xz
@ -219,6 +219,7 @@ Patch62: build-python.patch
Patch71: 0001-GLIBCXX-fix-for-GCC-12.patch
Patch73: D147266.diff
Patch74: D147267.diff
Patch75: mozilla-1773336.patch
# Test patches
# Generate without context by
@ -256,6 +257,11 @@ Patch427: D146087.diff
Patch428: D145725.diff
Patch429: D145966.diff
Patch430: D145871.diff
Patch431: D146271.diff
Patch432: D146272.diff
Patch433: D146273.diff
Patch434: D146274.diff
Patch435: D146275.diff
# NVIDIA mzbz#1735929
Patch440: D147635.diff
@ -480,6 +486,7 @@ This package contains results of tests executed during build.
%patch71 -p1 -b .0001-GLIBCXX-fix-for-GCC-12
%patch73 -p1 -b .D147266
%patch74 -p1 -b .D147267
%patch75 -p1 -b .mzbz#1773336
# Test patches
#%patch100 -p1 -b .firefox-tests-xpcshell
@ -514,6 +521,11 @@ This package contains results of tests executed during build.
%patch428 -p1 -b .D145725.diff
%patch429 -p1 -b .D145966.diff
%patch430 -p1 -b .D145871.diff
%patch431 -p1 -b .D146271.diff
%patch432 -p1 -b .D146272.diff
%patch433 -p1 -b .D146273.diff
%patch434 -p1 -b .D146274.diff
%patch435 -p1 -b .D146275.diff
# NVIDIA mzbz#1735929
%patch440 -p1 -b .D147635.diff
@ -1095,6 +1107,10 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
#---------------------------------------------------------------------
%changelog
* Thu Jun 9 2022 Martin Stransky <stransky@redhat.com>- 101.0.1-1
- Updated to 101.0.1
- More VA-API sandbox fixes (mzbz#1769182)
* Tue Jun 7 2022 Martin Stransky <stransky@redhat.com>- 101.0-2
- Enabled VA-API by default (+ added VA-API fixes from upstream)
- Fixed WebGL performance on NVIDIA drivers (mzbz#1735929)

12
mozilla-1773336.patch Normal file
View File

@ -0,0 +1,12 @@
diff -up firefox-101.0.1/gfx/webrender_bindings/webrender_ffi.h.old firefox-101.0.1/gfx/webrender_bindings/webrender_ffi.h
--- firefox-101.0.1/gfx/webrender_bindings/webrender_ffi.h.old 2022-06-09 10:31:16.122495733 +0200
+++ firefox-101.0.1/gfx/webrender_bindings/webrender_ffi.h 2022-06-09 10:31:22.880724352 +0200
@@ -72,8 +72,6 @@ struct WrPipelineInfo;
struct WrPipelineIdAndEpoch;
using WrPipelineIdEpochs = nsTArray<WrPipelineIdAndEpoch>;
-const uint64_t ROOT_CLIP_CHAIN = ~0;
-
} // namespace wr
} // namespace mozilla

View File

@ -1,4 +1,4 @@
SHA512 (mochitest-python.tar.gz) = 18e1aeb475df5fbf1fe3838897d5ac2f3114aa349030713fc2be27af087b1b12f57642621b87bd052f324a7cb7fbae5f36b21502191d85692f62c8cdd69c8bf2
SHA512 (firefox-101.0.source.tar.xz) = fffe7e0940c1443fcdc5b205677764cb4e04b29f33fcfafb2857d383700584f309806b81fc4989efb56cc12a3cca1ff7d451b647050c43e98777b5c952ed5d56
SHA512 (firefox-langpacks-101.0-20220530.tar.xz) = aa81113b6aef965aa17921d563759da6c499021b6f471369d998c35802f72e79a107080b4df59ca51dae15ac464176f23bce2fc84942f5852e810d963553b687
SHA512 (cbindgen-vendor.tar.xz) = 2bfec52455f133ede2fb7f7e8bcd358cb547a82cbb01e8cef477fe0700ebdfd9cf647cd93a6c11d3b321e441a142e26793c7a7865dba5c93033250ae78cf6b4b
SHA512 (firefox-101.0.1.source.tar.xz) = 435a7f6013582933e75c41e554a45beda30b5affd7d3ed7d2876026609ba7f17b2c20b507d9d0c9ce2379e335ec09b021257ba30ac55fabf02dca54b03ea70b4
SHA512 (firefox-langpacks-101.0.1-20220609.tar.xz) = 54c93a0fbded6a42948fd578e5577987186ca04695f9c0648718780d3a491b540187addf1239b13c53e532052888bd2ed76788a06c3a2422a060fb0da303ec58