summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/security/chromium-suid-sandbox.nix28
-rw-r--r--pkgs/applications/networking/browsers/chromium/common.nix4
-rw-r--r--pkgs/applications/networking/browsers/chromium/default.nix34
4 files changed, 64 insertions, 3 deletions
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index d202b5a2c724..6a6730856b15 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -92,6 +92,7 @@
   ./security/apparmor-suid.nix
   ./security/audit.nix
   ./security/ca.nix
+  ./security/chromium-suid-sandbox.nix
   ./security/duosec.nix
   ./security/grsecurity.nix
   ./security/hidepid.nix
diff --git a/nixos/modules/security/chromium-suid-sandbox.nix b/nixos/modules/security/chromium-suid-sandbox.nix
new file mode 100644
index 000000000000..b517e879f04e
--- /dev/null
+++ b/nixos/modules/security/chromium-suid-sandbox.nix
@@ -0,0 +1,28 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg     = config.security.chromiumSuidSandbox;
+  sandbox = pkgs.chromium.sandbox;
+in
+{
+  options.security.chromiumSuidSandbox.enable = mkEnableOption ''
+    Whether to install the Chromium SUID sandbox which is an executable that
+    Chromium may use in order to achieve sandboxing.
+
+    If you get the error "The SUID sandbox helper binary was found, but is not
+    configured correctly.", turning this on might help.
+
+    Also, if the URL chrome://sandbox tells you that "You are not adequately
+    sandboxed!", turning this on might resolve the issue.
+
+    Finally, if you have <option>security.grsecurity</option> enabled and you
+    use Chromium, you probably need this.
+  '';
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ sandbox ];
+    security.setuidPrograms    = [ sandbox.passthru.sandboxExecutableName ];
+  };
+}
diff --git a/pkgs/applications/networking/browsers/chromium/common.nix b/pkgs/applications/networking/browsers/chromium/common.nix
index 2c70978a4962..119a8c16f15c 100644
--- a/pkgs/applications/networking/browsers/chromium/common.nix
+++ b/pkgs/applications/networking/browsers/chromium/common.nix
@@ -96,6 +96,8 @@ let
   buildPath = "out/${buildType}";
   libExecPath = "$out/libexec/${packageName}";
 
+  sandboxExecutableName = "__chromium-suid-sandbox";
+
   base = rec {
     name = "${packageName}-${version}";
     inherit (upstream-info) version;
@@ -221,6 +223,8 @@ let
       targets = extraAttrs.buildTargets or [];
       commands = map buildCommand targets;
     in concatStringsSep "\n" commands;
+
+    passthru = { inherit sandboxExecutableName; };
   };
 
 # Remove some extraAttrs we supplied to the base attributes already.
diff --git a/pkgs/applications/networking/browsers/chromium/default.nix b/pkgs/applications/networking/browsers/chromium/default.nix
index a7447db7c220..8b4cb00a7786 100644
--- a/pkgs/applications/networking/browsers/chromium/default.nix
+++ b/pkgs/applications/networking/browsers/chromium/default.nix
@@ -1,4 +1,4 @@
-{ newScope, stdenv, makeWrapper, makeDesktopItem
+{ newScope, stdenv, makeWrapper, makeDesktopItem, writeScript
 
 # package customization
 , channel ? "stable"
@@ -61,22 +61,49 @@ let
 
   suffix = if channel != "stable" then "-" + channel else "";
 
+  sandboxExecutableName = chromium.browser.passthru.sandboxExecutableName;
+
 in stdenv.mkDerivation {
   name = "chromium${suffix}-${chromium.browser.version}";
 
   buildInputs = [ makeWrapper ];
 
+  outputs = ["out" "sandbox"];
+
   buildCommand = let
     browserBinary = "${chromium.browser}/libexec/chromium/chromium";
     getWrapperFlags = plugin: "$(< \"${plugin}/nix-support/wrapper-flags\")";
+    sandboxExecutableSourcePath = "${chromium.browser}/libexec/chromium/chrome-sandbox";
+    launchScript = writeScript "chromium" ''
+      #! ${stdenv.shell}
+
+      if [ -x "/var/setuid-wrappers/${sandboxExecutableName}" ]
+      then
+        export CHROME_DEVEL_SANDBOX="/var/setuid-wrappers/${sandboxExecutableName}"
+      else
+        export CHROME_DEVEL_SANDBOX="@sandbox@/bin/${sandboxExecutableName}"
+      fi
+
+      # libredirect causes chromium to deadlock on startup
+      export LD_PRELOAD="$(echo -n "$LD_PRELOAD" | tr ':' '\n' | grep -v /lib/libredirect\\.so$ | tr '\n' ':')"
+
+      exec @out@/bin/.chromium-wrapped "''${extraFlagsArray[@]}" "$@"
+    '';
   in with stdenv.lib; ''
     mkdir -p "$out/bin" "$out/share/applications"
 
     ln -s "${chromium.browser}/share" "$out/share"
-    eval makeWrapper "${browserBinary}" "$out/bin/chromium" \
-      --set CHROME_DEVEL_SANDBOX "${chromium.browser}/libexec/chromium/chrome-sandbox" \
+    eval makeWrapper "${browserBinary}" "$out/bin/.chromium-wrapped" \
       ${concatMapStringsSep " " getWrapperFlags chromium.plugins.enabled}
 
+    cp -v "${launchScript}" "$out/bin/chromium"
+    substituteInPlace $out/bin/chromium --replace @out@ $out --replace @sandbox@ $sandbox
+    chmod 755 "$out/bin/chromium"
+
+    mkdir -p "$sandbox/bin"
+    [ -x "${sandboxExecutableSourcePath}" ] || exit 1
+    ln -sv "${sandboxExecutableSourcePath}" "$sandbox/bin/${sandboxExecutableName}"
+
     ln -s "$out/bin/chromium" "$out/bin/chromium-browser"
     ln -s "${chromium.browser}/share/icons" "$out/share/icons"
     cp -v "${desktopItem}/share/applications/"* "$out/share/applications"
@@ -87,5 +114,6 @@ in stdenv.mkDerivation {
   passthru = {
     inherit (chromium) upstream-info;
     mkDerivation = chromium.mkChromiumDerivation;
+    inherit sandboxExecutableName;
   };
 }