Commit 65672f5b authored by Jed Davis's avatar Jed Davis Committed by jedavis@mozilla.com
Browse files

Bug 1302711 - Add Linux content sandbox level 6, for `ioctl` lockdown. r=gcp

The sandbox already limits `ioctl` attack surface by restricting what
files can be opened (you can't call a device's `ioctl` handler if you
can't get a fd for that device), but it's always good to have defense in
depth, especially when it can be implemented this simply.

The new policy is default-deny, allowing only a couple ioctls that
are really fcntls; others may be added as needed.

The old, default-allow policy (which blocked only tty ioctls) is still
available by lowering the pref `security.sandbox.content.level` to 5,
and for now that is also the case in safe mode.  (The safe mode sandbox
lowering may be removed in the future once this is better tested.)

Differential Revision: https://phabricator.services.mozilla.com/D249017
parent aebaac53
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1583,12 +1583,13 @@ pref("browser.bookmarks.editDialog.maxRecentFolders", 7);
  // 5 -> blocks access to GL / DRI / display servers
  //      (formerly the separate pref `security.sandbox.content.headless`)
  //      (side effect: sets MOZ_HEADLESS for content processes)
  // 6 -> default-deny for ioctl
  //
  // The purpose of this setting is to allow Linux users or distros to disable
  // the sandbox while we fix their problems, or to allow running Firefox with
  // exotic configurations we can't reasonably support out of the box.
  //
  pref("security.sandbox.content.level", 5);
  pref("security.sandbox.content.level", 6);
  // Introduced as part of bug 1608558.  Linux is currently the only platform
  // that uses a sandbox level for the socket process.  There are currently
  // only 2 levels:
+5 −1
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include "mozilla/SandboxSettings.h"
#include "mozISandboxSettings.h"
#include "nsServiceManagerUtils.h"
#include "nsAppRunner.h"

#include "mozilla/Components.h"
#include "mozilla/Preferences.h"
@@ -20,7 +21,6 @@
#ifdef XP_WIN
#  include "mozilla/gfx/gfxVars.h"
#  include "mozilla/WindowsVersion.h"
#  include "nsAppRunner.h"
#  include "nsExceptionHandler.h"
#  include "PDMFactory.h"
#endif  // XP_WIN
@@ -172,6 +172,10 @@ int GetEffectiveContentSandboxLevel() {
  if (level > 3 && !StaticPrefs::media_cubeb_sandbox()) {
    level = 3;
  }
  // Turn off ioctl lockdown in safe mode, until it's gotten more testing.
  if (level > 5 && gSafeMode) {
    level = 5;
  }
#endif
#if defined(XP_WIN)
  // Sandbox level 8, which uses a USER_RESTRICTED access token level, breaks if
+6 −0
Original line number Diff line number Diff line
@@ -556,6 +556,12 @@ void RunTestsContent(SandboxTestingChild* child) {
    munmap(mapping, kMapSize);
  }

  child->ErrnoValueTest("ioctl_dma_buf"_ns, ENOSYS, [] {
    // Attempt an arbitrary non-tty ioctl, on the wrong type of fd; if
    // allowed it would fail with ENOTTY (see the RDD tests) but in
    // this sandbox it should be blocked (ENOSYS).
    return ioctl(0, _IOW('b', 0, uint64_t), nullptr);
  });
#  endif  // XP_LINUX

#  ifdef XP_MACOSX
+4 −3
Original line number Diff line number Diff line
@@ -1485,9 +1485,10 @@ class ContentSandboxPolicy : public SandboxPolicyCommon {
        return If(request == FIOCLEX, Allow())
            // Rust's stdlib also uses FIONBIO instead of equivalent fcntls.
            .ElseIf(request == FIONBIO, Allow())
            // Allow anything that isn't a tty ioctl, for now; bug 1302711
            // will cover changing this to a default-deny policy.
            .ElseIf(shifted_type != kTtyIoctls, Allow())
            // Allow anything that isn't a tty ioctl, if level < 6
            .ElseIf(
                BelowLevel(6) ? shifted_type != kTtyIoctls : BoolConst(false),
                Allow())
            .Else(SandboxPolicyCommon::EvaluateSyscall(sysno));
      }