summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoachim Fasting <joachifm@fastmail.fm>2016-04-09 20:22:16 +0200
committerJoachim Fasting <joachifm@fastmail.fm>2016-04-10 12:27:06 +0200
commitcef2814a4f0530f6e020badc56dd808a96422a66 (patch)
tree6455422d43255cb6ac78ca343940516277425828
parent496a36980540390ac47e59310b3d73d516a531a2 (diff)
downloadnixpkgs-cef2814a4f0530f6e020badc56dd808a96422a66.tar
nixpkgs-cef2814a4f0530f6e020badc56dd808a96422a66.tar.gz
nixpkgs-cef2814a4f0530f6e020badc56dd808a96422a66.tar.bz2
nixpkgs-cef2814a4f0530f6e020badc56dd808a96422a66.tar.lz
nixpkgs-cef2814a4f0530f6e020badc56dd808a96422a66.tar.xz
nixpkgs-cef2814a4f0530f6e020badc56dd808a96422a66.tar.zst
nixpkgs-cef2814a4f0530f6e020badc56dd808a96422a66.zip
nixos: add optional process information hiding
This module adds an option `security.hideProcessInformation` that, when
enabled, restricts access to process information such as command-line
arguments to the process owner.  The module adds a static group "proc"
whose members are exempt from process information hiding.

Ideally, this feature would be implemented by simply adding the
appropriate mount options to `fileSystems."/proc".fsOptions`, but this
was found to not work in vmtests. To ensure that process information
hiding is enforced, we use a systemd service unit that remounts `/proc`
after `systemd-remount-fs.service` has completed.

To verify the correctness of the feature, simple tests were added to
nixos/tests/misc: the test ensures that unprivileged users cannot see
process information owned by another user, while members of "proc" CAN.

Thanks to @abbradar for feedback and suggestions.
-rw-r--r--nixos/modules/misc/ids.nix2
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/security/hidepid.nix42
-rw-r--r--nixos/tests/misc.nix9
4 files changed, 54 insertions, 0 deletions
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index 1e14fe655fc..3f2c735b221 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -47,6 +47,7 @@
       #floppy = 18; # unused
       #uucp = 19; # unused
       #lp = 20; # unused
+      #proc = 21; # unused
       pulseaudio = 22; # must match `pulseaudio' GID
       gpsd = 23;
       #cdrom = 24; # unused
@@ -288,6 +289,7 @@
       floppy = 18;
       uucp = 19;
       lp = 20;
+      proc = 21;
       pulseaudio = 22; # must match `pulseaudio' UID
       gpsd = 23;
       cdrom = 24;
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 7bcc5b84941..19c8db1039b 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -90,6 +90,7 @@
   ./security/ca.nix
   ./security/duosec.nix
   ./security/grsecurity.nix
+  ./security/hidepid.nix
   ./security/oath.nix
   ./security/pam.nix
   ./security/pam_usb.nix
diff --git a/nixos/modules/security/hidepid.nix b/nixos/modules/security/hidepid.nix
new file mode 100644
index 00000000000..8271578c55d
--- /dev/null
+++ b/nixos/modules/security/hidepid.nix
@@ -0,0 +1,42 @@
+{ config, pkgs, lib, ... }:
+with lib;
+
+{
+  options = {
+    security.hideProcessInformation = mkEnableOption "" // { description = ''
+      Restrict access to process information to the owning user.  Enabling
+      this option implies, among other things, that command-line arguments
+      remain private.  This option is recommended for most systems, unless
+      there's a legitimate reason for allowing unprivileged users to inspect
+      the process information of other users.
+
+      Members of the group "proc" are exempt from process information hiding.
+      To allow a service to run without process information hiding, add "proc"
+      to its supplementary groups via
+      <option>systemd.services.&lt;name?&gt;.serviceConfig.SupplementaryGroups</option>.
+    ''; };
+  };
+
+  config = mkIf config.security.hideProcessInformation {
+    users.groups.proc.gid = config.ids.gids.proc;
+
+    systemd.services.hidepid = {
+      wantedBy = [ "local-fs.target" ];
+      after = [ "systemd-remount-fs.service" ];
+      before = [ "local-fs-pre.target" "local-fs.target" "shutdown.target" ];
+      wants = [ "local-fs-pre.target" ];
+
+      serviceConfig = {
+        Type = "oneshot";
+        RemainAfterExit = true;
+        ExecStart = ''${pkgs.utillinux}/bin/mount -o remount,hidepid=2,gid=${toString config.ids.gids.proc} /proc'';
+        ExecStop = ''${pkgs.utillinux}/bin/mount -o remount,hidepid=0,gid=0 /proc'';
+      };
+
+      unitConfig = {
+        DefaultDependencies = false;
+        Conflicts = "shutdown.target";
+      };
+    };
+  };
+}
diff --git a/nixos/tests/misc.nix b/nixos/tests/misc.nix
index b926a62194b..cd4086cb8f6 100644
--- a/nixos/tests/misc.nix
+++ b/nixos/tests/misc.nix
@@ -25,6 +25,8 @@ import ./make-test.nix ({ pkgs, ...} : {
         };
       users.users.sybil = { isNormalUser = true; group = "wheel"; };
       security.sudo = { enable = true; wheelNeedsPassword = false; };
+      security.hideProcessInformation = true;
+      users.users.alice = { isNormalUser = true; extraGroups = [ "proc" ]; };
     };
 
   testScript =
@@ -117,5 +119,12 @@ import ./make-test.nix ({ pkgs, ...} : {
       subtest "sudo", sub {
           $machine->succeed("su - sybil -c 'sudo true'");
       };
+
+      # Test hidepid
+      subtest "hidepid", sub {
+          $machine->succeed("grep -Fq hidepid=2 /etc/mtab");
+          $machine->succeed("[ `su - sybil -c 'pgrep -c -u root'` = 0 ]");
+          $machine->succeed("[ `su - alice -c 'pgrep -c -u root'` != 0 ]");
+      };
     '';
 })