Bug 1445003 - Detect RenderDoc and adjust the sandbox policy so it can work. r=gcp
RenderDoc, a graphics debugging tool, uses a preload library that
creates a listening socket (Internet-domain) early in startup and
accepts connections from the frontend. If it's detected (via env vars),
we allow accept/accept4 (but not socket/bind/listen), and remain in
the parent process's network namespace so that other processes can
connect to the socket.
This doesn't change the sandbox policy if not running under RenderDoc.
MozReview-Commit-ID: 964RW4BFh4u
--- a/security/sandbox/linux/SandboxFilter.cpp
+++ b/security/sandbox/linux/SandboxFilter.cpp
@@ -374,16 +374,17 @@ public:
// interception in support of a semantic sandboxing layer. On B2G
// this is the Android process permission model; on desktop,
// namespaces and chroot() will be used.
class ContentSandboxPolicy : public SandboxPolicyCommon {
private:
SandboxBrokerClient* mBroker;
ContentProcessSandboxParams mParams;
bool mAllowSysV;
+ bool mUsingRenderDoc;
bool BelowLevel(int aLevel) const {
return mParams.mLevel < aLevel;
}
ResultExpr AllowBelowLevel(int aLevel, ResultExpr aOrElse) const {
return BelowLevel(aLevel) ? Allow() : Move(aOrElse);
}
ResultExpr AllowBelowLevel(int aLevel) const {
@@ -739,16 +740,17 @@ private:
}
public:
ContentSandboxPolicy(SandboxBrokerClient* aBroker,
ContentProcessSandboxParams&& aParams)
: mBroker(aBroker)
, mParams(Move(aParams))
, mAllowSysV(PR_GetEnv("MOZ_SANDBOX_ALLOW_SYSV") != nullptr)
+ , mUsingRenderDoc(PR_GetEnv("RENDERDOC_CAPTUREOPTS") != nullptr)
{ }
~ContentSandboxPolicy() override = default;
Maybe<ResultExpr> EvaluateSocketCall(int aCall, bool aHasArgs) const override {
switch(aCall) {
case SYS_RECVFROM:
case SYS_SENDTO:
@@ -785,16 +787,22 @@ public:
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_ACCEPT:
+ case SYS_ACCEPT4:
+ if (mUsingRenderDoc) {
+ return Some(Allow());
+ }
+ return SandboxPolicyCommon::EvaluateSocketCall(aCall, aHasArgs);
case SYS_RECV:
case SYS_SEND:
case SYS_GETSOCKOPT:
case SYS_SETSOCKOPT:
case SYS_GETSOCKNAME:
case SYS_GETPEERNAME:
case SYS_SHUTDOWN:
return Some(Allow());
--- a/security/sandbox/linux/launch/SandboxLaunch.cpp
+++ b/security/sandbox/linux/launch/SandboxLaunch.cpp
@@ -272,18 +272,19 @@ SandboxLaunchPrepare(GeckoProcessType aT
#endif
#ifdef MOZ_CONTENT_SANDBOX
case GeckoProcessType_Content:
if (level >= 4) {
canChroot = true;
// Unshare network namespace if allowed by graphics; see
// function definition above for details. (The display
// local-ness is cached because it won't change.)
- static const bool isDisplayLocal = IsDisplayLocal();
- if (isDisplayLocal) {
+ static const bool canCloneNet =
+ IsDisplayLocal() && !PR_GetEnv("RENDERDOC_CAPTUREOPTS");
+ if (canCloneNet) {
flags |= CLONE_NEWNET;
}
}
// Hidden pref to allow testing user namespaces separately, even
// if there's nothing that would require them.
if (Preferences::GetBool("security.sandbox.content.force-namespace", false)) {
flags |= CLONE_NEWUSER;
}