Bug 1450740 - Don't sandbox network namespace when X11 named sockets aren't accessible. r=gcp draft
authorJed Davis <jld@mozilla.com>
Mon, 02 Apr 2018 15:19:04 -0600
changeset 776838 2fa8ed232266c374812c3583cb4b10cc58f95da8
parent 776308 e1dd5af91068dc36b3715f3bf5f0741fa69fa29a
push id105019
push userbmo:jld@mozilla.com
push dateTue, 03 Apr 2018 20:57:17 +0000
reviewersgcp
bugs1450740
milestone61.0a1
Bug 1450740 - Don't sandbox network namespace when X11 named sockets aren't accessible. r=gcp MozReview-Commit-ID: KiL4GwMms3a
security/sandbox/linux/launch/SandboxLaunch.cpp
--- a/security/sandbox/linux/launch/SandboxLaunch.cpp
+++ b/security/sandbox/linux/launch/SandboxLaunch.cpp
@@ -27,16 +27,17 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/Move.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/SandboxReporter.h"
 #include "mozilla/SandboxSettings.h"
 #include "mozilla/Services.h"
 #include "mozilla/Unused.h"
 #include "nsCOMPtr.h"
+#include "nsDebug.h"
 #include "nsIGfxInfo.h"
 #include "nsString.h"
 #include "nsThreadUtils.h"
 #include "prenv.h"
 #include "sandbox/linux/system_headers/linux_syscalls.h"
 
 #ifdef MOZ_X11
 #ifndef MOZ_WIDGET_GTK
@@ -81,24 +82,40 @@ IsDisplayLocal()
 
     int domain;
     socklen_t optlen = static_cast<socklen_t>(sizeof(domain));
     int rv = getsockopt(xSocketFd, SOL_SOCKET, SO_DOMAIN, &domain, &optlen);
     if (NS_WARN_IF(rv != 0)) {
       return false;
     }
     MOZ_RELEASE_ASSERT(static_cast<size_t>(optlen) == sizeof(domain));
-    // There's one more wrinkle here: the network namespace also
-    // controls "abstract namespace" addresses in the Unix domain.
-    // Xorg seems to listen on both abstract and normal addresses, but
-    // prefers abstract. This mean that if there exists a server that
-    // uses only the abstract namespace, then it will break and we
-    // won't be able to detect that ahead of time.  So, hopefully it
-    // does not exist.
-    return domain == AF_LOCAL;
+    if (domain != AF_LOCAL) {
+      return false;
+    }
+    // There's one more complication: Xorg listens on named sockets
+    // (actual filesystem nodes) as well as abstract addresses (opaque
+    // octet strings scoped to the network namespace; this is a Linux
+    // extension).
+    //
+    // Inside a container environment (e.g., when running as a Snap
+    // package), it's possible that only the abstract addresses are
+    // accessible.  In that case, the display must be considered
+    // remote.  See also bug 1450740.
+    //
+    // Unfortunately, the Xorg client libraries prefer the abstract
+    // addresses, so this isn't directly detectable by inspecting the
+    // parent process's socket.  Instead, this checks for the
+    // directory the sockets are stored in, which typically won't
+    // exist in a container with a private /tmp that isn't running its
+    // own X server.
+    if (access("/tmp/.X11-unix", X_OK) != 0) {
+      NS_ERROR("/tmp/.X11-unix is inaccessible; can't isolate network"
+               " namespace in content processes");
+      return false;
+    }
   }
 #endif
 
   // Assume that other backends (e.g., Wayland) will not use the
   // network namespace.
   return true;
 }