Bug 1199481 - Complain more when entering sandboxing code as root. r=kang
authorJed Davis <jld@mozilla.com>
Fri, 28 Aug 2015 13:37:00 +0200
changeset 294352 10e3f62dc8a66c514fd1b3b42604cc5b7be8ebdc
parent 294351 0d99e927527b2300dacfbc641e4af1249f46d604
child 294353 78050272add479077443c9cc8dfba6f55be933b9
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskang
bugs1199481
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1199481 - Complain more when entering sandboxing code as root. r=kang
security/sandbox/linux/LinuxCapabilities.h
security/sandbox/linux/Sandbox.cpp
--- a/security/sandbox/linux/LinuxCapabilities.h
+++ b/security/sandbox/linux/LinuxCapabilities.h
@@ -79,16 +79,25 @@ public:
   }
 
   void Normalize() {
     for (size_t i = 0; i < _LINUX_CAPABILITY_U32S_3; ++i) {
       mBits[i].permitted |= mBits[i].effective | mBits[i].inheritable;
     }
   }
 
+  bool AnyEffective() const {
+    for (size_t i = 0; i < _LINUX_CAPABILITY_U32S_3; ++i) {
+      if (mBits[i].effective != 0) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   // These three methods expose individual bits in the three
   // capability sets as objects that can be used as bool lvalues.
   // The argument is the capability number, as defined in
   // the <linux/capability.h> header.
   BitRef Effective(unsigned aCap)
   {
     return GenericBitRef(&__user_cap_data_struct::effective, aCap);
   }
--- a/security/sandbox/linux/Sandbox.cpp
+++ b/security/sandbox/linux/Sandbox.cpp
@@ -553,18 +553,32 @@ SandboxEarlyInit(GeckoProcessType aType,
     break;
   }
 
   // If there's nothing to do, then we're done.
   if (!canChroot && !canUnshareNet && !canUnshareIPC) {
     return;
   }
 
+  {
+    LinuxCapabilities existingCaps;
+    if (existingCaps.GetCurrent() && existingCaps.AnyEffective()) {
+      SANDBOX_LOG_ERROR("PLEASE DO NOT RUN THIS AS ROOT.  Strange things may"
+                        " happen when capabilities are dropped.");
+    }
+  }
+
   // If capabilities can't be gained, then nothing can be done.
   if (!info.Test(SandboxInfo::kHasUserNamespaces)) {
+    // Drop any existing capabilities; unsharing the user namespace
+    // would implicitly drop them, so if we're running in a broken
+    // configuration where that would matter (e.g., running as root
+    // from a non-root-owned mode-0700 directory) this means it will
+    // break the same way on all kernels and be easier to troubleshoot.
+    LinuxCapabilities().SetCurrent();
     return;
   }
 
   // The failure cases for the various unshares, and setting up the
   // chroot helper, don't strictly need to be fatal -- but they also
   // shouldn't fail on any reasonable system, so let's take the small
   // risk of breakage over the small risk of quietly providing less
   // security than we expect.  (Unlike in SandboxInfo, this is in the