about summary refs log tree commit diff
path: root/nixos/modules/security
diff options
context:
space:
mode:
authorParnell Springmeyer <parnell@digitalmentat.com>2017-02-13 18:03:06 -0600
committerParnell Springmeyer <parnell@digitalmentat.com>2017-02-13 18:03:06 -0600
commitcca2e1155617304b5bcb3457309983cf8e99b067 (patch)
tree37d5b7f682e972cbd927428b681a4e09e5941429 /nixos/modules/security
parent9e36a58649199a16a15cba3c78966ab0538a6fd7 (diff)
Resurrecting the single-wrapper read from sibling .real file behavior
Diffstat (limited to 'nixos/modules/security')
-rw-r--r--nixos/modules/security/wrappers/default.nix44
-rw-r--r--nixos/modules/security/wrappers/wrapper.c28
2 files changed, 39 insertions, 33 deletions
diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix
index 757765ed08c45..0548b1d965933 100644
--- a/nixos/modules/security/wrappers/default.nix
+++ b/nixos/modules/security/wrappers/default.nix
@@ -8,24 +8,20 @@ let
       (n: v: (if v ? "program" then v else v // {program=n;}))
       wrappers);
 
-  mkWrapper = { program, source ? null, ...}:
-    let buildWrapper = ''
-          parentWrapperDir=$(dirname ${wrapperDir})
-          gcc -Wall -O2 -DSOURCE_PROG=\"${source}\" -DWRAPPER_DIR=\"$parentWrapperDir\" \
-              -Wformat -Wformat-security -Werror=format-security \
-              -fstack-protector-strong --param ssp-buffer-size=4 \
-              -D_FORTIFY_SOURCE=2 -fPIC \
-              -lcap-ng -lcap ${./wrapper.c} -o $out/bin/${program}.wrapper -L ${pkgs.libcap.lib}/lib -L ${pkgs.libcap_ng}/lib \
-              -I ${pkgs.libcap.dev}/include -I ${pkgs.libcap_ng}/include -I ${pkgs.linuxHeaders}/include
-        '';
-    in pkgs.stdenv.mkDerivation {
-      name         = "${program}-wrapper";
-      unpackPhase  = "true";
-      installPhase = ''
-        mkdir -p $out/bin
-        ${buildWrapper}
-      '';
-    };
+  securityWrapper = pkgs.stdenv.mkDerivation {
+    name         = "security-wrapper";
+    unpackPhase  = "true";
+    installPhase = ''
+      mkdir -p $out/bin
+      parentWrapperDir=$(dirname ${wrapperDir})
+      gcc -Wall -O2 -DWRAPPER_DIR=\"$parentWrapperDir\" \
+          -Wformat -Wformat-security -Werror=format-security \
+          -fstack-protector-strong --param ssp-buffer-size=4 \
+          -D_FORTIFY_SOURCE=2 -fPIC \
+          -lcap-ng -lcap ${./wrapper.c} -o $out/bin/security-wrapper -L ${pkgs.libcap.lib}/lib -L ${pkgs.libcap_ng}/lib \
+          -I ${pkgs.libcap.dev}/include -I ${pkgs.libcap_ng}/include -I ${pkgs.linuxHeaders}/include
+    '';
+  };
 
   ###### Activation script for the setcap wrappers
   mkSetcapProgram =
@@ -37,9 +33,9 @@ let
     , ...
     }:
     assert (lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3");
-    let wrapperDrv = mkWrapper { inherit program source; };
-    in ''
-      cp ${wrapperDrv}/bin/${program}.wrapper $wrapperDir/${program}
+    ''
+      cp ${securityWrapper}/bin/security-wrapper $wrapperDir/${program}
+      echo -n "$source" > $wrapperDir/${program}.real
 
       # Prevent races
       chmod 0000 $wrapperDir/${program}
@@ -65,9 +61,9 @@ let
     , permissions ? "u+rx,g+x,o+x"
     , ...
     }:
-    let wrapperDrv = mkWrapper { inherit program source; };
-    in ''
-      cp ${wrapperDrv}/bin/${program}.wrapper $wrapperDir/${program}
+    ''
+      cp ${securityWrapper}/bin/security-wrapper $wrapperDir/${program}
+      echo -n "$source" > $wrapperDir/${program}.real
 
       # Prevent races
       chmod 0000 $wrapperDir/${program}
diff --git a/nixos/modules/security/wrappers/wrapper.c b/nixos/modules/security/wrappers/wrapper.c
index e6f2605143fe4..4a656c54e3f9c 100644
--- a/nixos/modules/security/wrappers/wrapper.c
+++ b/nixos/modules/security/wrappers/wrapper.c
@@ -21,9 +21,8 @@
 
 extern char **environ;
 
-// The SOURCE_PROG and WRAPPER_DIR macros are supplied at compile time
-// for a security reason: So they cannot be changed at runtime.
-static char * sourceProg = SOURCE_PROG;
+// The WRAPPER_DIR macro is supplied at compile time so that it cannot
+// be changed at runtime
 static char * wrapperDir = WRAPPER_DIR;
 
 // Wrapper debug variable name
@@ -207,14 +206,25 @@ int main(int argc, char * * argv)
     // And, of course, we shouldn't be writable.
     assert(!(st.st_mode & (S_IWGRP | S_IWOTH)));
 
-    struct stat stR;
-    stat(sourceProg, &stR);
+    // Read the path of the real (wrapped) program from <self>.real.
+    char realFN[PATH_MAX + 10];
+    int realFNSize = snprintf (realFN, sizeof(realFN), "%s.real", selfPath);
+    assert (realFNSize < sizeof(realFN));
 
-    // Make sure the program we're wrapping is non-zero
-    assert(stR.st_size > 0);
+    int fdSelf = open(realFN, O_RDONLY);
+    assert (fdSelf != -1);
 
-    // Read the capabilities set on the file and raise them in to the
-    // Ambient set so the program we're wrapping receives the
+    char sourceProg[PATH_MAX];
+    len = read(fdSelf, sourceProg, PATH_MAX);
+    assert (len != -1);
+    assert (len < sizeof(sourceProg));
+    assert (len > 0);
+    sourceProg[len] = 0;
+
+    close(fdSelf);
+
+    // Read the capabilities set on the wrapper and raise them in to
+    // the Ambient set so the program we're wrapping receives the
     // capabilities too!
     make_caps_ambient(selfPath);