Resurrecting the single-wrapper read from sibling .real file behavior
This commit is contained in:
parent
9e36a58649
commit
cca2e11556
@ -8,24 +8,20 @@ let
|
|||||||
(n: v: (if v ? "program" then v else v // {program=n;}))
|
(n: v: (if v ? "program" then v else v // {program=n;}))
|
||||||
wrappers);
|
wrappers);
|
||||||
|
|
||||||
mkWrapper = { program, source ? null, ...}:
|
securityWrapper = pkgs.stdenv.mkDerivation {
|
||||||
let buildWrapper = ''
|
name = "security-wrapper";
|
||||||
parentWrapperDir=$(dirname ${wrapperDir})
|
unpackPhase = "true";
|
||||||
gcc -Wall -O2 -DSOURCE_PROG=\"${source}\" -DWRAPPER_DIR=\"$parentWrapperDir\" \
|
installPhase = ''
|
||||||
-Wformat -Wformat-security -Werror=format-security \
|
mkdir -p $out/bin
|
||||||
-fstack-protector-strong --param ssp-buffer-size=4 \
|
parentWrapperDir=$(dirname ${wrapperDir})
|
||||||
-D_FORTIFY_SOURCE=2 -fPIC \
|
gcc -Wall -O2 -DWRAPPER_DIR=\"$parentWrapperDir\" \
|
||||||
-lcap-ng -lcap ${./wrapper.c} -o $out/bin/${program}.wrapper -L ${pkgs.libcap.lib}/lib -L ${pkgs.libcap_ng}/lib \
|
-Wformat -Wformat-security -Werror=format-security \
|
||||||
-I ${pkgs.libcap.dev}/include -I ${pkgs.libcap_ng}/include -I ${pkgs.linuxHeaders}/include
|
-fstack-protector-strong --param ssp-buffer-size=4 \
|
||||||
'';
|
-D_FORTIFY_SOURCE=2 -fPIC \
|
||||||
in pkgs.stdenv.mkDerivation {
|
-lcap-ng -lcap ${./wrapper.c} -o $out/bin/security-wrapper -L ${pkgs.libcap.lib}/lib -L ${pkgs.libcap_ng}/lib \
|
||||||
name = "${program}-wrapper";
|
-I ${pkgs.libcap.dev}/include -I ${pkgs.libcap_ng}/include -I ${pkgs.linuxHeaders}/include
|
||||||
unpackPhase = "true";
|
'';
|
||||||
installPhase = ''
|
};
|
||||||
mkdir -p $out/bin
|
|
||||||
${buildWrapper}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
###### Activation script for the setcap wrappers
|
###### Activation script for the setcap wrappers
|
||||||
mkSetcapProgram =
|
mkSetcapProgram =
|
||||||
@ -37,9 +33,9 @@ let
|
|||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
assert (lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3");
|
assert (lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3");
|
||||||
let wrapperDrv = mkWrapper { inherit program source; };
|
''
|
||||||
in ''
|
cp ${securityWrapper}/bin/security-wrapper $wrapperDir/${program}
|
||||||
cp ${wrapperDrv}/bin/${program}.wrapper $wrapperDir/${program}
|
echo -n "$source" > $wrapperDir/${program}.real
|
||||||
|
|
||||||
# Prevent races
|
# Prevent races
|
||||||
chmod 0000 $wrapperDir/${program}
|
chmod 0000 $wrapperDir/${program}
|
||||||
@ -65,9 +61,9 @@ let
|
|||||||
, permissions ? "u+rx,g+x,o+x"
|
, permissions ? "u+rx,g+x,o+x"
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
let wrapperDrv = mkWrapper { inherit program source; };
|
''
|
||||||
in ''
|
cp ${securityWrapper}/bin/security-wrapper $wrapperDir/${program}
|
||||||
cp ${wrapperDrv}/bin/${program}.wrapper $wrapperDir/${program}
|
echo -n "$source" > $wrapperDir/${program}.real
|
||||||
|
|
||||||
# Prevent races
|
# Prevent races
|
||||||
chmod 0000 $wrapperDir/${program}
|
chmod 0000 $wrapperDir/${program}
|
||||||
|
@ -21,9 +21,8 @@
|
|||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
// The SOURCE_PROG and WRAPPER_DIR macros are supplied at compile time
|
// The WRAPPER_DIR macro is supplied at compile time so that it cannot
|
||||||
// for a security reason: So they cannot be changed at runtime.
|
// be changed at runtime
|
||||||
static char * sourceProg = SOURCE_PROG;
|
|
||||||
static char * wrapperDir = WRAPPER_DIR;
|
static char * wrapperDir = WRAPPER_DIR;
|
||||||
|
|
||||||
// Wrapper debug variable name
|
// Wrapper debug variable name
|
||||||
@ -207,14 +206,25 @@ int main(int argc, char * * argv)
|
|||||||
// And, of course, we shouldn't be writable.
|
// And, of course, we shouldn't be writable.
|
||||||
assert(!(st.st_mode & (S_IWGRP | S_IWOTH)));
|
assert(!(st.st_mode & (S_IWGRP | S_IWOTH)));
|
||||||
|
|
||||||
struct stat stR;
|
// Read the path of the real (wrapped) program from <self>.real.
|
||||||
stat(sourceProg, &stR);
|
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
|
int fdSelf = open(realFN, O_RDONLY);
|
||||||
assert(stR.st_size > 0);
|
assert (fdSelf != -1);
|
||||||
|
|
||||||
// Read the capabilities set on the file and raise them in to the
|
char sourceProg[PATH_MAX];
|
||||||
// Ambient set so the program we're wrapping receives the
|
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!
|
// capabilities too!
|
||||||
make_caps_ambient(selfPath);
|
make_caps_ambient(selfPath);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user