Bug 1450740 - Don't sandbox network namespace when X11 named sockets aren't accessible. r=gcp, a=RyanVM
authorJed Davis <jld@mozilla.com>
Mon, 02 Apr 2018 15:19:04 -0600
changeset 463104 73fab5fbc84369a3fd29c592301187f1e445e481
parent 463103 28514415973b9e4c714fb27066352d1534ebf19d
child 463105 64b1913329634cbba8bb270f224f36807bf5a65f
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgcp, RyanVM
bugs1450740
milestone60.0
Bug 1450740 - Don't sandbox network namespace when X11 named sockets aren't accessible. r=gcp, a=RyanVM 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;
 }