From ad9bfe2254e6205f94baa9c988063b0737911a23 Mon Sep 17 00:00:00 2001
From: Emily <vcs@emily.moe>
Date: Sat, 4 Apr 2020 23:13:27 +0100
Subject: [PATCH] nixos/hardened: enable user namespaces for root

linux-hardened sets kernel.unprivileged_userns_clone=0 by default; see
anthraxx/linux-hardened@104f44058f058a395502192c4939645df6f52ecb.

This allows the Nix sandbox to function while reducing the attack
surface posed by user namespaces, which allow unprivileged code to
exercise lots of root-only code paths and have lead to privilege
escalation vulnerabilities in the past.

We can safely leave user namespaces on for privileged users, as root
already has root privileges, but if you're not running builds on your
machine and really want to minimize the kernel attack surface then you
can set security.allowUserNamespaces to false.

Note that Chrome's sandbox requires either unprivileged CLONE_NEWUSER or
setuid, and Firefox's silently reduces the security level if it isn't
allowed (see about:support), so desktop users may want to set:

    boot.kernel.sysctl."kernel.unprivileged_userns_clone" = true;
---
 nixos/modules/profiles/hardened.nix | 2 --
 nixos/tests/hardened.nix            | 3 ++-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/nixos/modules/profiles/hardened.nix b/nixos/modules/profiles/hardened.nix
index 09a1dd543331..c771a4ed328a 100644
--- a/nixos/modules/profiles/hardened.nix
+++ b/nixos/modules/profiles/hardened.nix
@@ -21,8 +21,6 @@ with lib;
 
   security.lockKernelModules = mkDefault true;
 
-  security.allowUserNamespaces = mkDefault false;
-
   security.protectKernelImage = mkDefault true;
 
   security.allowSimultaneousMultithreading = mkDefault false;
diff --git a/nixos/tests/hardened.nix b/nixos/tests/hardened.nix
index cbf76f9e5587..21bc9308aaa3 100644
--- a/nixos/tests/hardened.nix
+++ b/nixos/tests/hardened.nix
@@ -76,7 +76,8 @@ import ./make-test.nix ({ pkgs, ...} : {
 
       # Test userns
       subtest "userns", sub {
-          $machine->fail("unshare --user");
+          $machine->succeed("unshare --user true");
+          $machine->fail("su -l alice -c 'unshare --user true'");
       };
 
       # Test dmesg restriction