From 5deed1cb86a8d0f9cf4523113f92ac8b1b25dca3 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 30 Jun 2016 18:59:18 -0500 Subject: [PATCH 01/74] network-interfaces: use setcap-wrappers for ping and ping6 iff linux kernel is at-least 4.3 --- nixos/modules/tasks/network-interfaces.nix | 23 ++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index c52bd904cae..588a328192d 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs, utils, ... }: +{ config, lib, pkgs, utils, stdenv, ... }: with lib; with utils; @@ -889,7 +889,26 @@ in (i: flip map [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${i.name}.proxy_arp" true)) )); - security.setuidPrograms = [ "ping" "ping6" ]; + # Capabilities won't work unless we have at-least a 4.3 Linux + # kernel because we need the ambient capability + security.setcapCapabilities = mkIf (versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.3") ( + [ + { program = "ping"; + setcap = true; + capabilities = "cap_net_raw+p"; + } + + { program = "ping6"; + setcap = true; + capabilities = "cap_net_raw+p"; + } + ] + ); + + # If our linux kernel IS older than 4.3, let's setuid ping and ping6 + security.setuidPrograms = mkIf (versionOlder (getVersion config.boot.kernelPackages.kernel) "4.3") ( + [ "ping" "ping6" ] + ); # Set the host and domain names in the activation script. Don't # clear it if it's not configured in the NixOS configuration, From bfc3956376128b9560926f6c122a49d809b4be97 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 30 Jun 2016 18:59:32 -0500 Subject: [PATCH 02/74] security: adding setcap-wrapper functionality --- nixos/modules/security/setcap-wrapper.c | 210 +++++++++++++++++++++ nixos/modules/security/setcap-wrappers.nix | 165 ++++++++++++++++ 2 files changed, 375 insertions(+) create mode 100644 nixos/modules/security/setcap-wrapper.c create mode 100644 nixos/modules/security/setcap-wrappers.nix diff --git a/nixos/modules/security/setcap-wrapper.c b/nixos/modules/security/setcap-wrapper.c new file mode 100644 index 00000000000..a44d174d90f --- /dev/null +++ b/nixos/modules/security/setcap-wrapper.c @@ -0,0 +1,210 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Make sure assertions are not compiled out, we use them to codify +// invariants about this program and we want it to fail fast and +// loudly if they are violated. +#undef NDEBUG + +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; +static char * wrapperDir = WRAPPER_DIR; + +// Update the capabilities of the running process to include the given +// capability in the Ambient set. +static void set_ambient_cap(cap_value_t cap) +{ + capng_get_caps_process(); + + if (capng_update(CAPNG_ADD, CAPNG_INHERITABLE, (unsigned long) cap)) + { + printf("cannot raise the capability into the Inheritable set\n"); + exit(1); + } + + capng_apply(CAPNG_SELECT_CAPS); + + if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (unsigned long) cap, 0, 0)) + { + perror("cannot raise the capability into the Ambient set\n"); + exit(1); + } +} + +// Given the path to this program, fetch its configured capability set +// (as set by `setcap ... /path/to/file`) and raise those capabilities +// into the Ambient set. +static int make_caps_ambient(const char *selfPath) +{ + cap_t caps = cap_get_file(selfPath); + + if(!caps) + { + fprintf(stderr, "could not retreive the capability set for this file\n"); + return 1; + } + + // We use `cap_to_text` and iteration over the tokenized result + // string because, as of libcap's current release, there is no + // facility for retrieving an array of `cap_value_t`'s that can be + // given to `prctl` in order to lift that capability into the + // Ambient set. + // + // Some discussion was had around shot-gunning all of the + // capabilities we know about into the Ambient set but that has a + // security smell and I deemed the risk of the current + // implementation crashing the program to be lower than the risk + // of a privilege escalation security hole being introduced by + // raising all capabilities, even ones we didn't intend for the + // program, into the Ambient set. + // + // `cap_t` which is returned by `cap_get_*` is an opaque type and + // even if we could retrieve the bitmasks (which, as far as I can + // tell we cannot) in order to get the `cap_value_t` + // representation for each capability we would have to take the + // total number of capabilities supported and iterate over the + // sequence of integers up-to that maximum total, testing each one + // against the bitmask ((bitmask >> n) & 1) to see if it's set and + // aggregating each "capability integer n" that is set in the + // bitmask. + // + // That, combined with the fact that we can't easily get the + // bitmask anyway seemed much more brittle than fetching the + // `cap_t`, transforming it into a textual representation, + // tokenizing the string, and using `cap_from_name` on the token + // to get the `cap_value_t` that we need for `prctl`. There is + // indeed risk involved if the output string format of + // `cap_to_text` ever changes but at this time the combination of + // factors involving the below list have led me to the conclusion + // that the best implementation at this time is reading then + // parsing with *lots of documentation* about why we're doing it + // this way. + // + // 1. No explicit API for fetching an array of `cap_value_t`'s or + // for transforming a `cap_t` into such a representation + // 2. The risk of a crash is lower than lifting all capabilities + // into the Ambient set + // 3. libcap is depended on heavily in the Linux ecosystem so + // there is a high chance that the output representation of + // `cap_to_text` will not change which reduces our risk that + // this parsing step will cause a crash + // + // The preferred method, should it ever be available in the + // future, would be to use libcap API's to transform the result + // from a `cap_get_*` into an array of `cap_value_t`'s that can + // then be given to prctl. + // + // - Parnell + ssize_t capLen; + char* capstr = cap_to_text(caps, &capLen); + cap_free(caps); + + // TODO: For now, we assume that cap_to_text always starts its + // result string with " =" and that the first capability is listed + // immediately after that. We should verify this. + assert(capLen >= 2); + capstr += 2; + + char* saveptr = NULL; + for(char* tok = strtok_r(capstr, ",", &saveptr); tok; tok = strtok_r(NULL, ",", &saveptr)) + { + cap_value_t capnum; + if (cap_from_name(tok, &capnum)) + { + fprintf(stderr, "cap_from_name failed, skipping: %s\n", tok); + } + else if (capnum == CAP_SETPCAP) + { + // Check for the cap_setpcap capability, we set this on the + // wrapper so it can elevate the capabilities to the Ambient + // set but we do not want to propagate it down into the + // wrapped program. + // + // TODO: what happens if that's the behavior you want + // though???? I'm preferring a strict vs. loose policy here. + fprintf(stderr, "cap_setpcap in set, skipping it\n"); + } + else + { + set_ambient_cap(capnum); + printf("raised %s into the Ambient capability set\n", tok); + } + } + cap_free(capstr); + + return 0; +} + +int main(int argc, char * * argv) +{ + // I *think* it's safe to assume that a path from a symbolic link + // should safely fit within the PATH_MAX system limit. Though I'm + // not positive it's safe... + char selfPath[PATH_MAX]; + int selfPathSize = readlink("/proc/self/exe", selfPath, sizeof(selfPath) - 1); + + assert(selfPathSize > 0); + + selfPath[selfPathSize] = '\0'; + + // Make sure that we are being executed from the right location, + // i.e., `safeWrapperDir'. This is to prevent someone from creating + // hard link `X' from some other location, along with a false + // `X.real' file, to allow arbitrary programs from being executed + // with elevated capabilities. + int len = strlen(wrapperDir); + if (len > 0 && '/' == wrapperDir[len - 1]) + --len; + assert(!strncmp(selfPath, wrapperDir, len)); + assert('/' == wrapperDir[0]); + assert('/' == selfPath[len]); + + // Make *really* *really* sure that we were executed as + // `selfPath', and not, say, as some other setuid program. That + // is, our effective uid/gid should match the uid/gid of + // `selfPath'. + struct stat st; + assert(lstat(selfPath, &st) != -1); + + assert(!(st.st_mode & S_ISUID) || (st.st_uid == geteuid())); + assert(!(st.st_mode & S_ISGID) || (st.st_gid == getegid())); + + // And, of course, we shouldn't be writable. + assert(!(st.st_mode & (S_IWGRP | S_IWOTH))); + + struct stat stR; + stat(sourceProg, &stR); + + // Make sure the program we're wrapping is non-zero + assert(stR.st_size > 0); + + // Read the capabilities set on the file and raise them in to the + // Ambient set so the program we're wrapping receives the + // capabilities too! + assert(!make_caps_ambient(selfPath)); + + execve(sourceProg, argv, environ); + + fprintf(stderr, "%s: cannot run `%s': %s\n", + argv[0], sourceProg, strerror(errno)); + + exit(1); +} + + diff --git a/nixos/modules/security/setcap-wrappers.nix b/nixos/modules/security/setcap-wrappers.nix new file mode 100644 index 00000000000..a9e3f8c0b1c --- /dev/null +++ b/nixos/modules/security/setcap-wrappers.nix @@ -0,0 +1,165 @@ +{ config, lib, pkgs, ... }: + +with lib; with pkgs; + +let + + inherit (config.security) setcapWrapperDir; + + cfg = config.security.setcapCapabilities; + + # Produce a shell-code splice intended to be stitched into one of + # the build or install phases within the `setcapWrapper` derivation. + mkSetcapWrapper = { program, source ? null, ...}: + '' + if ! source=${if source != null then source else "$(readlink -f $(PATH=$SETCAP_PATH type -tP ${program}))"}; then + # If we can't find the program, fall back to the + # system profile. + source=/nix/var/nix/profiles/default/bin/${program} + fi + + gcc -Wall -O2 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${setcapWrapperDir}\" \ + -lcap-ng -lcap ${./setcap-wrapper.c} -o $out/bin/${program}.wrapper + ''; + + setcapWrappers = + + # This is only useful for Linux platforms and a kernel version of + # 4.3 or greater + assert pkgs.stdenv.isLinux; + assert versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.3"; + + pkgs.stdenv.mkDerivation { + name = "setcap-wrapper"; + unpackPhase = "true"; + buildInputs = [ linuxHeaders_4_4 libcap libcap_ng ]; + installPhase = '' + mkdir -p $out/bin + + # Concat together all of our shell splices to compile + # binary wrapper programs for all configured setcap programs. + ${concatMapStrings mkSetcapWrapper cfg} + ''; + }; +in +{ + options = { + security.setcapCapabilities = mkOption { + type = types.listOf types.attrs; + default = []; + example = + [ { program = "sendmail"; + source = "${pkgs.sendmail.bin}/bin/sendmail"; + owner = "nobody"; + group = "postdrop"; + setcap = true; + capabilities = "cap_net_raw+ep"; + } + ]; + description = '' + This option sets capabilities on a wrapper program that + propagates those capabilities down to the wrapped, real + program. + + The `program` attribute is the name of the program to be + wrapped. If no `source` attribute is provided, specifying the + absolute path to the program, then the program will be + searched for in the path environment variable. + + NOTE: cap_setpcap, which is required for the wrapper program + to be able to raise caps into the Ambient set is NOT raised to + the Ambient set so that the real program cannot modify its own + capabilities!! This may be too restrictive for cases in which + the real program needs cap_setpcap but it at least leans on + the side security paranoid vs. too relaxed. + + The attribute `setcap` defaults to false and it will create a + wrapper program but never set the capability set on it. This + is done so that you can remove a capability sent entirely from + a wrapper program without also needing to go change any + absolute paths that may be directly referencing the wrapper + program. + ''; + }; + + security.setcapWrapperDir = mkOption { + type = types.path; + default = "/nix/var/setcap-wrappers"; + internal = true; + description = '' + This option defines the path to the setcap wrappers. It + should generally not be overriden. + ''; + }; + + }; + + config = { + + # Make sure our setcap-wrapper dir exports to the PATH env + # variable when initializing the shell + environment.extraInit = '' + # The setcap wrappers override other bin directories. + export PATH="${config.security.setcapWrapperDir}:$PATH" + ''; + + + + system.activationScripts.setcap = + let + setcapPrograms = cfg; + configureSetcapWrapper = + { program + , capabilities + , source ? null + , owner ? "nobody" + , group ? "nogroup" + , setcap ? false + }: + '' + mkdir -p ${setcapWrapperDir} + + cp ${setcapWrappers}/bin/${program}.wrapper ${setcapWrapperDir}/${program} + + # Prevent races + chmod 0000 ${setcapWrapperDir}/${program} + chown ${owner}.${group} ${setcapWrapperDir}/${program} + + # Set desired capabilities on the file plus cap_setpcap so + # the wrapper program can elevate the capabilities set on + # its file into the Ambient set. + # + # Only set the capabilities though if we're being told to + # do so. + ${ + if setcap then + '' + ${libcap.out}/bin/setcap "cap_setpcap,${capabilities}" ${setcapWrapperDir}/${program} + '' + else "" + } + + # Set the executable bit + chmod u+rx,g+x,o+x ${setcapWrapperDir}/${program} + ''; + + in stringAfter [ "users" ] + '' + # Look in the system path and in the default profile for + # programs to be wrapped. + SETCAP_PATH=${config.system.path}/bin:${config.system.path}/sbin + + # When a program is removed from the security.setcapCapabilities + # list we have to remove all of the previous program wrappers + # and re-build them minus the wrapper for the program removed, + # hence the rm here in the activation script. + + rm -f ${setcapWrapperDir}/* + + # Concatenate the generated shell slices to configure + # wrappers for each program needing specialized capabilities. + + ${concatMapStrings configureSetcapWrapper setcapPrograms} + ''; + }; +} From b3d63f81919d1da80b28362cbc6368d42d0deb68 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 30 Jun 2016 19:14:14 -0500 Subject: [PATCH 03/74] security: whitespace wibble --- nixos/modules/security/setcap-wrappers.nix | 2 -- 1 file changed, 2 deletions(-) diff --git a/nixos/modules/security/setcap-wrappers.nix b/nixos/modules/security/setcap-wrappers.nix index a9e3f8c0b1c..dbd40e266ba 100644 --- a/nixos/modules/security/setcap-wrappers.nix +++ b/nixos/modules/security/setcap-wrappers.nix @@ -103,8 +103,6 @@ in export PATH="${config.security.setcapWrapperDir}:$PATH" ''; - - system.activationScripts.setcap = let setcapPrograms = cfg; From 00dc2c559ca98c449253ae0090cb227a3d4c59e1 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 30 Jun 2016 19:21:12 -0500 Subject: [PATCH 04/74] installer: adding mkdir command for the setcap-wrappers dir --- nixos/modules/installer/tools/nixos-install.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh index 589a51fa709..f9412ed444e 100644 --- a/nixos/modules/installer/tools/nixos-install.sh +++ b/nixos/modules/installer/tools/nixos-install.sh @@ -92,12 +92,14 @@ fi mkdir -m 0755 -p $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/etc $mountPoint/run $mountPoint/home mkdir -m 01777 -p $mountPoint/tmp mkdir -m 0755 -p $mountPoint/tmp/root +mkdir -m 0755 -p $mountPoint/var/permissions-wrappers mkdir -m 0700 -p $mountPoint/root mount --rbind /dev $mountPoint/dev mount --rbind /proc $mountPoint/proc mount --rbind /sys $mountPoint/sys mount --rbind / $mountPoint/tmp/root mount -t tmpfs -o "mode=0755" none $mountPoint/run +mount -t tmpfs -o "mode=0755" none $mountPoint/var/permissions-wrappers rm -rf $mountPoint/var/run ln -s /run $mountPoint/var/run for f in /etc/resolv.conf /etc/hosts; do rm -f $mountPoint/$f; [ -f "$f" ] && cp -Lf $f $mountPoint/etc/; done From 6fe93ae42add1ac9174909a3b69e4c4cb2d82b33 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 30 Jun 2016 19:21:48 -0500 Subject: [PATCH 05/74] installer: adding perl 'next if' skip command for setcap-wrappers dir --- nixos/modules/installer/tools/nixos-generate-config.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl index 5e576367eb2..2190cac53d9 100644 --- a/nixos/modules/installer/tools/nixos-generate-config.pl +++ b/nixos/modules/installer/tools/nixos-generate-config.pl @@ -329,6 +329,7 @@ foreach my $fs (read_file("/proc/self/mountinfo")) { # Skip special filesystems. next if in($mountPoint, "/proc") || in($mountPoint, "/dev") || in($mountPoint, "/sys") || in($mountPoint, "/run") || $mountPoint eq "/var/lib/nfs/rpc_pipefs"; next if $mountPoint eq "/var/setuid-wrappers"; + next if $mountPoint eq "/var/setcap-wrappers"; # Skip the optional fields. my $n = 6; $n++ while $fields[$n] ne "-"; $n++; From 12a23b3d913573d6d7dbd202e00e4c6a1102d6fc Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 30 Jun 2016 19:22:19 -0500 Subject: [PATCH 06/74] boot: create setcap-wrappers dir as a tmpfs --- nixos/modules/system/boot/stage-2-init.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/nixos/modules/system/boot/stage-2-init.sh b/nixos/modules/system/boot/stage-2-init.sh index 704150e77d7..946897b1c43 100644 --- a/nixos/modules/system/boot/stage-2-init.sh +++ b/nixos/modules/system/boot/stage-2-init.sh @@ -141,6 +141,11 @@ if [ -n "@useHostResolvConf@" -a -e /etc/resolv.conf ]; then cat /etc/resolv.conf | resolvconf -m 1000 -a host fi +# Create /var/permissions-wrappers as a tmpfs. +rm -rf /var/permissions-wrappers +mkdir -m 0755 -p /var/permissions-wrappers +mount -t tmpfs -o "mode=0755" tmpfs /var/permissions-wrappers + # Log the script output to /dev/kmsg or /run/log/stage-2-init.log. # Only at this point are all the necessary prerequisites ready for these commands. exec {logOutFd}>&1 {logErrFd}>&2 From 1c0f672f7ae2d7d1db29b7d1a4ed2181e71538b8 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 30 Jun 2016 19:23:19 -0500 Subject: [PATCH 07/74] security: update setcap-wrappers dir to match the system-level dir we're creating on init --- nixos/modules/security/setcap-wrappers.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/security/setcap-wrappers.nix b/nixos/modules/security/setcap-wrappers.nix index dbd40e266ba..faebc6f7e0d 100644 --- a/nixos/modules/security/setcap-wrappers.nix +++ b/nixos/modules/security/setcap-wrappers.nix @@ -84,7 +84,7 @@ in security.setcapWrapperDir = mkOption { type = types.path; - default = "/nix/var/setcap-wrappers"; + default = "/var/setcap-wrappers"; internal = true; description = '' This option defines the path to the setcap wrappers. It From 4e98aa639f9161fe461ba1c2e4f31519f9d89569 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Fri, 1 Jul 2016 11:07:16 -0500 Subject: [PATCH 08/74] module-list: adding setcap-wrappers to the import list --- nixos/modules/module-list.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index dfc1d694e97..dde0be5c14c 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -104,6 +104,7 @@ ./security/rngd.nix ./security/rtkit.nix ./security/setuid-wrappers.nix + ./security/setcap-wrappers.nix ./security/sudo.nix ./services/amqp/activemq/default.nix ./services/amqp/rabbitmq.nix From 2efb60c8e9c502b0fb4df81b03700b600118722a Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Fri, 1 Jul 2016 11:09:14 -0500 Subject: [PATCH 09/74] security: tweaking the setcap-wrapper example to be more relevant --- nixos/modules/security/setcap-wrappers.nix | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/nixos/modules/security/setcap-wrappers.nix b/nixos/modules/security/setcap-wrappers.nix index faebc6f7e0d..b8383d81358 100644 --- a/nixos/modules/security/setcap-wrappers.nix +++ b/nixos/modules/security/setcap-wrappers.nix @@ -48,10 +48,9 @@ in type = types.listOf types.attrs; default = []; example = - [ { program = "sendmail"; - source = "${pkgs.sendmail.bin}/bin/sendmail"; + [ { program = "ping"; owner = "nobody"; - group = "postdrop"; + group = "nogroup"; setcap = true; capabilities = "cap_net_raw+ep"; } From 79f1a1e07ae758de73cd640faf488a0bf1c479b8 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Fri, 1 Jul 2016 11:53:21 -0500 Subject: [PATCH 10/74] security: need to specify the ping binary paths for setcap wrappers. --- nixos/modules/tasks/network-interfaces.nix | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 588a328192d..12605c24516 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -894,11 +894,13 @@ in security.setcapCapabilities = mkIf (versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.3") ( [ { program = "ping"; + source = "${pkgs.iputils.out}/bin/ping"; setcap = true; capabilities = "cap_net_raw+p"; } { program = "ping6"; + source = "${pkgs.iputils.out}/bin/ping6"; setcap = true; capabilities = "cap_net_raw+p"; } From c16647ec29ab46b52cd365220288a8222cfcdad3 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Fri, 1 Jul 2016 15:54:33 -0500 Subject: [PATCH 11/74] security: switching to linuxHeaders so we always stay current with the selected kernel. --- nixos/modules/security/setcap-wrappers.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/security/setcap-wrappers.nix b/nixos/modules/security/setcap-wrappers.nix index b8383d81358..ead3cb219f1 100644 --- a/nixos/modules/security/setcap-wrappers.nix +++ b/nixos/modules/security/setcap-wrappers.nix @@ -32,7 +32,7 @@ let pkgs.stdenv.mkDerivation { name = "setcap-wrapper"; unpackPhase = "true"; - buildInputs = [ linuxHeaders_4_4 libcap libcap_ng ]; + buildInputs = [ linuxHeaders libcap libcap_ng ]; installPhase = '' mkdir -p $out/bin From 79e81aa31bc7a0fa88507c06f21b41fbbd1cb863 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Fri, 15 Jul 2016 18:05:28 -0500 Subject: [PATCH 12/74] security: Removing the old wrappers and replacing with 'permissions-wrappers' --- .../security/permissions-wrappers/default.nix | 201 ++++++++++++++++++ .../permissions-wrapper.c} | 24 ++- .../setcap-wrapper-drv.nix | 37 ++++ .../setcap-wrappers.nix | 0 .../setuid-wrapper-drv.nix | 36 ++++ .../setuid-wrappers.nix | 0 nixos/modules/security/setuid-wrapper.c | 81 ------- 7 files changed, 293 insertions(+), 86 deletions(-) create mode 100644 nixos/modules/security/permissions-wrappers/default.nix rename nixos/modules/security/{setcap-wrapper.c => permissions-wrappers/permissions-wrapper.c} (95%) create mode 100644 nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix rename nixos/modules/security/{ => permissions-wrappers}/setcap-wrappers.nix (100%) create mode 100644 nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix rename nixos/modules/security/{ => permissions-wrappers}/setuid-wrappers.nix (100%) delete mode 100644 nixos/modules/security/setuid-wrapper.c diff --git a/nixos/modules/security/permissions-wrappers/default.nix b/nixos/modules/security/permissions-wrappers/default.nix new file mode 100644 index 00000000000..a4491946df5 --- /dev/null +++ b/nixos/modules/security/permissions-wrappers/default.nix @@ -0,0 +1,201 @@ +{ config, lib, pkgs, ... }: +let + + inherit (config.security) permissionsWrapperDir; + + cfg = config.security.permissionsWrappers; + + setcapWrappers = import ./setcap-wrapper-drv.nix { }; + setuidWrappers = import ./setuid-wrapper-drv.nix { }; + + ###### Activation script for the setcap wrappers + configureSetcapWrapper = + { program + , capabilities + , source ? null + , owner ? "nobody" + , group ? "nogroup" + , setcap ? false + }: + '' + cp ${setcapWrappers}/bin/${program}.wrapper ${permissionsWrapperDir}/${program} + + # Prevent races + chmod 0000 ${permissionsWrapperDir}/${program} + chown ${owner}.${group} ${permissionsWrapperDir}/${program} + + # Set desired capabilities on the file plus cap_setpcap so + # the wrapper program can elevate the capabilities set on + # its file into the Ambient set. + # + # Only set the capabilities though if we're being told to + # do so. + ${ + if setcap then + '' + ${pkgs.libcap.out}/bin/setcap "cap_setpcap,${capabilities}" ${permissionsWrapperDir}/${program} + '' + else "" + } + + # Set the executable bit + chmod u+rx,g+x,o+x ${permissionsWrapperDir}/${program} + ''; + + ###### Activation script for the setuid wrappers + setuidPrograms = + (map (x: { program = x; owner = "root"; group = "root"; setuid = true; }) + config.security.setuidPrograms) + ++ config.security.setuidOwners; + + makeSetuidWrapper = + { program + , source ? null + , owner ? "nobody" + , group ? "nogroup" + , setuid ? false + , setgid ? false + , permissions ? "u+rx,g+x,o+x" + }: + + '' + cp ${setuidWrappers}/bin/${program}.wrapper ${permissionsWrapperDir}/${program} + + # Prevent races + chmod 0000 ${permissionsWrapperDir}/${program} + chown ${owner}.${group} ${permissionsWrapperDir}/${program} + + chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" ${permissionsWrapperDir}/${program} + ''; +in +{ + + ###### interface + + options = { + security.permissionsWrappers.setcap = mkOption { + type = types.listOf types.attrs; + default = []; + example = + [ { program = "ping"; + source = "${pkgs.iputils.out}/bin/ping" + owner = "nobody"; + group = "nogroup"; + setcap = true; + capabilities = "cap_net_raw+ep"; + } + ]; + description = '' + This option sets capabilities on a wrapper program that + propagates those capabilities down to the wrapped, real + program. + + The `program` attribute is the name of the program to be + wrapped. If no `source` attribute is provided, specifying the + absolute path to the program, then the program will be + searched for in the path environment variable. + + NOTE: cap_setpcap, which is required for the wrapper program + to be able to raise caps into the Ambient set is NOT raised to + the Ambient set so that the real program cannot modify its own + capabilities!! This may be too restrictive for cases in which + the real program needs cap_setpcap but it at least leans on + the side security paranoid vs. too relaxed. + + The attribute `setcap` defaults to false and it will create a + wrapper program but never set the capability set on it. This + is done so that you can remove a capability sent entirely from + a wrapper program without also needing to go change any + absolute paths that may be directly referencing the wrapper + program. + ''; + }; + + security.permissionsWrappers.setuid = mkOption { + type = types.listOf types.attrs; + default = []; + example = + [ { program = "sendmail"; + source = "${pkgs.sendmail.bin}/bin/sendmail"; + owner = "nobody"; + group = "postdrop"; + setuid = false; + setgid = true; + permissions = "u+rx,g+x,o+x"; + } + ]; + description = '' + This option allows the ownership and permissions on the setuid + wrappers for specific programs to be overridden from the + default (setuid root, but not setgid root). + ''; + }; + + security.permissionsWrapperDir = mkOption { + type = types.path; + default = "/var/permissions-wrappers"; + internal = true; + description = '' + This option defines the path to the permissions wrappers. It + should not be overriden. + ''; + }; + + }; + + + ###### implementation + + config = { + + # Make sure our setcap-wrapper dir exports to the PATH env + # variable when initializing the shell + environment.extraInit = '' + # The permissions wrappers override other bin directories. + export PATH="${config.security.permissionsWrapperDir}:$PATH" + ''; + + ###### setcap activation script + system.activationScripts.setcap = + stringAfter [ "users" ] + '' + # Look in the system path and in the default profile for + # programs to be wrapped. + PERMISSIONS_WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin + + # When a program is removed from the security.permissionsWrappers.setcap + # list we have to remove all of the previous program wrappers + # and re-build them minus the wrapper for the program removed, + # hence the rm here in the activation script. + + rm -f ${permissionsWrapperDir}/* + + # Concatenate the generated shell slices to configure + # wrappers for each program needing specialized capabilities. + + ${concatMapStrings configureSetcapWrapper cfg.setcap} + ''; + + ###### setuid activation script + system.activationScripts.setuid = + stringAfter [ "users" ] + '' + # Look in the system path and in the default profile for + # programs to be wrapped. + PERMISSIONS_WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin + + # When a program is removed from the security.permissionsWrappers.setcap + # list we have to remove all of the previous program wrappers + # and re-build them minus the wrapper for the program removed, + # hence the rm here in the activation script. + + rm -f ${permissionsWrapperDir}/* + + # Concatenate the generated shell slices to configure + # wrappers for each program needing specialized capabilities. + + ${concatMapStrings configureSetuidWrapper cfg.setuid} + ''; + + }; +} diff --git a/nixos/modules/security/setcap-wrapper.c b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c similarity index 95% rename from nixos/modules/security/setcap-wrapper.c rename to nixos/modules/security/permissions-wrappers/permissions-wrapper.c index a44d174d90f..effdaa93096 100644 --- a/nixos/modules/security/setcap-wrapper.c +++ b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c @@ -8,11 +8,6 @@ #include #include #include -#include -#include -#include -#include -#include // Make sure assertions are not compiled out, we use them to codify // invariants about this program and we want it to fail fast and @@ -26,6 +21,24 @@ extern char **environ; static char * sourceProg = SOURCE_PROG; static char * wrapperDir = WRAPPER_DIR; +// Make sure we have the WRAPPER_TYPE macro specified at compile +// time... +#ifdef WRAPPER_SETCAP +static char * wrapperType = "setcap"; +#elif defined WRAPPER_SETUID +static char * wrapperType = "setuid"; +#else +fprintf(stderr, "Program must be compiled with either the WRAPPER_SETCAP or WRAPPER_SETUID macros specified!\n"); +exit(1); +#endif + +#ifdef WRAPPER_SETCAP +#include +#include +#include +#include +#include + // Update the capabilities of the running process to include the given // capability in the Ambient set. static void set_ambient_cap(cap_value_t cap) @@ -150,6 +163,7 @@ static int make_caps_ambient(const char *selfPath) return 0; } +#endif int main(int argc, char * * argv) { diff --git a/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix b/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix new file mode 100644 index 00000000000..f64c683f6e8 --- /dev/null +++ b/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix @@ -0,0 +1,37 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.security.permissionsWrappers; + + # Produce a shell-code splice intended to be stitched into one of + # the build or install phases within the derivation. + mkSetcapWrapper = { program, source ? null, ...}: + '' + if ! source=${if source != null then source else "$(readlink -f $(PATH=$PERMISSIONS_WRAPPER_PATH type -tP ${program}))"}; then + # If we can't find the program, fall back to the + # system profile. + source=/nix/var/nix/profiles/default/bin/${program} + fi + + gcc -Wall -O2 -DWRAPPER_SETCAP=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${cfg.permissionsWrapperDir}\" \ + -lcap-ng -lcap ${./permissions-wrapper.c} -o $out/bin/${program}.wrapper + ''; +in + +# This is only useful for Linux platforms and a kernel version of +# 4.3 or greater +assert pkgs.stdenv.isLinux; +assert lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3"; + +pkgs.stdenv.mkDerivation { + name = "setcap-wrapper"; + unpackPhase = "true"; + buildInputs = [ pkgs.linuxHeaders pkgs.libcap pkgs.libcap_ng ]; + installPhase = '' + mkdir -p $out/bin + + # Concat together all of our shell splices to compile + # binary wrapper programs for all configured setcap programs. + ${concatMapStrings mkSetcapWrapper cfg.setcap} + ''; +}; diff --git a/nixos/modules/security/setcap-wrappers.nix b/nixos/modules/security/permissions-wrappers/setcap-wrappers.nix similarity index 100% rename from nixos/modules/security/setcap-wrappers.nix rename to nixos/modules/security/permissions-wrappers/setcap-wrappers.nix diff --git a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix b/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix new file mode 100644 index 00000000000..15dc1918b5c --- /dev/null +++ b/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix @@ -0,0 +1,36 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.security.permissionsWrappers; + + # Produce a shell-code splice intended to be stitched into one of + # the build or install phases within the derivation. + mkSetuidWrapper = { program, source ? null, ...}: + '' + if ! source=${if source != null then source else "$(readlink -f $(PATH=$PERMISSIONS_WRAPPER_PATH type -tP ${program}))"}; then + # If we can't find the program, fall back to the + # system profile. + source=/nix/var/nix/profiles/default/bin/${program} + fi + + gcc -Wall -O2 -DWRAPPER_SETUID=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${cfg.permissionsWrapperDir}\" \ + -lcap-ng -lcap ${./permissions-wrapper.c} -o $out/bin/${program}.wrapper + ''; +in + +# This is only useful for Linux platforms and a kernel version of +# 4.3 or greater +assert pkgs.stdenv.isLinux; +assert lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3"; + +pkgs.stdenv.mkDerivation { + name = "setuid-wrapper"; + unpackPhase = "true"; + installPhase = '' + mkdir -p $out/bin + + # Concat together all of our shell splices to compile + # binary wrapper programs for all configured setcap programs. + ${concatMapStrings mkSetuidWrapper cfg.setuid} + ''; +}; diff --git a/nixos/modules/security/setuid-wrappers.nix b/nixos/modules/security/permissions-wrappers/setuid-wrappers.nix similarity index 100% rename from nixos/modules/security/setuid-wrappers.nix rename to nixos/modules/security/permissions-wrappers/setuid-wrappers.nix diff --git a/nixos/modules/security/setuid-wrapper.c b/nixos/modules/security/setuid-wrapper.c deleted file mode 100644 index ffd0b65b762..00000000000 --- a/nixos/modules/security/setuid-wrapper.c +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Make sure assertions are not compiled out. */ -#undef NDEBUG - -extern char **environ; - -static char * wrapperDir = WRAPPER_DIR; - -int main(int argc, char * * argv) -{ - char self[PATH_MAX]; - - int len = readlink("/proc/self/exe", self, sizeof(self) - 1); - assert (len > 0); - self[len] = 0; - - /* Make sure that we are being executed from the right location, - i.e., `wrapperDir'. This is to prevent someone from - creating hard link `X' from some other location, along with a - false `X.real' file, to allow arbitrary programs from being - executed setuid. */ - assert ((strncmp(self, wrapperDir, strlen(wrapperDir)) == 0) && - (self[strlen(wrapperDir)] == '/')); - - /* Make *really* *really* sure that we were executed as `self', - and not, say, as some other setuid program. That is, our - effective uid/gid should match the uid/gid of `self'. */ - //printf("%d %d\n", geteuid(), getegid()); - - struct stat st; - assert (lstat(self, &st) != -1); - - //printf("%d %d\n", st.st_uid, st.st_gid); - - assert ((st.st_mode & S_ISUID) == 0 || - (st.st_uid == geteuid())); - - assert ((st.st_mode & S_ISGID) == 0 || - st.st_gid == getegid()); - - /* And, of course, we shouldn't be writable. */ - assert (!(st.st_mode & (S_IWGRP | S_IWOTH))); - - - /* Read the path of the real (wrapped) program from .real. */ - char realFN[PATH_MAX + 10]; - int realFNSize = snprintf (realFN, sizeof(realFN), "%s.real", self); - assert (realFNSize < sizeof(realFN)); - - int fdSelf = open(realFN, O_RDONLY); - assert (fdSelf != -1); - - char real[PATH_MAX]; - len = read(fdSelf, real, PATH_MAX); - assert (len != -1); - assert (len < sizeof (real)); - assert (len > 0); - real[len] = 0; - - close(fdSelf); - - //printf("real = %s, len = %d\n", real, len); - - execve(real, argv, environ); - - fprintf(stderr, "%s: cannot run `%s': %s\n", - argv[0], real, strerror(errno)); - - exit(1); -} From 81b33eb46645b1bd3ab5029c0ca2012a24902bb0 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Fri, 15 Jul 2016 18:15:08 -0500 Subject: [PATCH 13/74] security: Updating the machinery for creating the wrapper programs dir in var and updating ping and ping6 for changed config interface. --- .../installer/tools/nixos-generate-config.pl | 3 +-- nixos/modules/module-list.nix | 3 +-- nixos/modules/tasks/network-interfaces.nix | 20 ++++++++++++++++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl index 2190cac53d9..4da752e1905 100644 --- a/nixos/modules/installer/tools/nixos-generate-config.pl +++ b/nixos/modules/installer/tools/nixos-generate-config.pl @@ -328,8 +328,7 @@ foreach my $fs (read_file("/proc/self/mountinfo")) { # Skip special filesystems. next if in($mountPoint, "/proc") || in($mountPoint, "/dev") || in($mountPoint, "/sys") || in($mountPoint, "/run") || $mountPoint eq "/var/lib/nfs/rpc_pipefs"; - next if $mountPoint eq "/var/setuid-wrappers"; - next if $mountPoint eq "/var/setcap-wrappers"; + next if $mountPoint eq "/var/permissions-wrappers"; # Skip the optional fields. my $n = 6; $n++ while $fields[$n] ne "-"; $n++; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index dde0be5c14c..6e69cebf763 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -103,8 +103,7 @@ ./security/prey.nix ./security/rngd.nix ./security/rtkit.nix - ./security/setuid-wrappers.nix - ./security/setcap-wrappers.nix + ./security/permissions-wrappers ./security/sudo.nix ./services/amqp/activemq/default.nix ./services/amqp/rabbitmq.nix diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 12605c24516..1e0b874297a 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -891,7 +891,7 @@ in # Capabilities won't work unless we have at-least a 4.3 Linux # kernel because we need the ambient capability - security.setcapCapabilities = mkIf (versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.3") ( + security.permissionsWrappers.setcap = mkIf (versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.3") ( [ { program = "ping"; source = "${pkgs.iputils.out}/bin/ping"; @@ -908,8 +908,22 @@ in ); # If our linux kernel IS older than 4.3, let's setuid ping and ping6 - security.setuidPrograms = mkIf (versionOlder (getVersion config.boot.kernelPackages.kernel) "4.3") ( - [ "ping" "ping6" ] + security.permissionsWrappers.setuid = mkIf (versionOlder (getVersion config.boot.kernelPackages.kernel) "4.3") ( + [ + { program = "ping"; + source = "${pkgs.iputils.out}/bin/ping"; + owner = "root"; + group = "root"; + setuid = true; + } + + { program = "ping6"; + source = "${pkgs.iputils.out}/bin/ping6"; + owner = "root"; + group = "root"; + setuid = true; + } + ] ); # Set the host and domain names in the activation script. Don't From 390ab0b3eff809052d5b9d9b5335413b36898481 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Fri, 15 Jul 2016 19:10:48 -0500 Subject: [PATCH 14/74] everything?: Updating every package that depended on the old setuidPrograms configuration. --- nixos/modules/programs/kbdlight.nix | 9 +++- nixos/modules/programs/light.nix | 9 +++- nixos/modules/programs/shadow.nix | 47 +++++++++++++++++-- nixos/modules/rename.nix | 1 - nixos/modules/security/duosec.nix | 12 ++++- nixos/modules/security/pam.nix | 21 ++++++++- nixos/modules/security/pam_usb.nix | 21 +++++++-- .../security/permissions-wrappers/default.nix | 5 -- nixos/modules/security/polkit.nix | 10 +++- nixos/modules/security/sudo.nix | 17 ++++++- nixos/modules/services/mail/exim.nix | 10 +++- nixos/modules/services/scheduling/cron.nix | 10 +++- nixos/modules/services/scheduling/fcron.nix | 10 +++- .../x11/desktop-managers/enlightenment.nix | 10 +++- pkgs/desktops/enlightenment/enlightenment.nix | 6 +-- 15 files changed, 170 insertions(+), 28 deletions(-) diff --git a/nixos/modules/programs/kbdlight.nix b/nixos/modules/programs/kbdlight.nix index 0172368e968..c3ea6b5e973 100644 --- a/nixos/modules/programs/kbdlight.nix +++ b/nixos/modules/programs/kbdlight.nix @@ -11,6 +11,13 @@ in config = mkIf cfg.enable { environment.systemPackages = [ pkgs.kbdlight ]; - security.setuidPrograms = [ "kbdlight" ]; + + security.permissionsWrappers.setuid = + [ { program = "kbdlight"; + source = "${pkgs.kbdlight.out}/bin/kbdlight"; + user = "root"; + group = "root"; + setuid = true; + }]; }; } diff --git a/nixos/modules/programs/light.nix b/nixos/modules/programs/light.nix index 09cd1113d9c..d141eaf66f7 100644 --- a/nixos/modules/programs/light.nix +++ b/nixos/modules/programs/light.nix @@ -21,6 +21,13 @@ in config = mkIf cfg.enable { environment.systemPackages = [ pkgs.light ]; - security.setuidPrograms = [ "light" ]; + + security.permissionsWrappers.setuid = + [ { program = "light"; + source = "${pkgs.light.out}/bin/light"; + user = "root"; + group = "root"; + setuid = true; + }]; }; } diff --git a/nixos/modules/programs/shadow.nix b/nixos/modules/programs/shadow.nix index 878c9cc0cf0..8ee324eaf63 100644 --- a/nixos/modules/programs/shadow.nix +++ b/nixos/modules/programs/shadow.nix @@ -102,11 +102,48 @@ in chgpasswd = { rootOK = true; }; }; - security.setuidPrograms = [ "su" "chfn" ] - ++ [ "newuidmap" "newgidmap" ] # new in shadow 4.2.x - ++ lib.optionals config.users.mutableUsers - [ "passwd" "sg" "newgrp" ]; + security.setuidPrograms = + [ + { program = "su"; + source = "${pkgs.shadow.su}/bin/su"; + user = "root"; + group = "root"; + setuid = true; + } + { program = "chfn"; + source = "${pkgs.shadow.out}/bin/chfn"; + user = "root"; + group = "root"; + setuid = true; + } + ] ++ + (lib.optionals config.users.mutableUsers + map (x: x // { user = "root"; + group = "root"; + setuid = true; + }) + [ + { program = "passwd"; + source = "${pkgs.shadow.out}/bin/passwd"; + } + + { program = "sg"; + source = "${pkgs.shadow.out}/bin/sg"; + } + + { program = "newgrp"; + source = "${pkgs.shadow.out}/bin/newgrp"; + } + + { program = "newuidmap"; + source = "${pkgs.shadow.out}/bin/newuidmap"; + } + + { program = "newgidmap"; + source = "${pkgs.shadow.out}/bin/newgidmap"; + } + ] + ); }; - } diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index 412cccc20d5..e4584146d6f 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -10,7 +10,6 @@ with lib; (mkRenamedOptionModule [ "fonts" "enableFontConfig" ] [ "fonts" "fontconfig" "enable" ]) (mkRenamedOptionModule [ "fonts" "extraFonts" ] [ "fonts" "fonts" ]) - (mkRenamedOptionModule [ "security" "extraSetuidPrograms" ] [ "security" "setuidPrograms" ]) (mkRenamedOptionModule [ "networking" "enableWLAN" ] [ "networking" "wireless" "enable" ]) (mkRenamedOptionModule [ "networking" "enableRT73Firmware" ] [ "networking" "enableRalinkFirmware" ]) diff --git a/nixos/modules/security/duosec.nix b/nixos/modules/security/duosec.nix index 0e3a54325ca..202218c915c 100644 --- a/nixos/modules/security/duosec.nix +++ b/nixos/modules/security/duosec.nix @@ -193,7 +193,17 @@ in ]; environment.systemPackages = [ pkgs.duo-unix ]; - security.setuidPrograms = [ "login_duo" ]; + + security.permissionsWrappers.setuid = + [ + { program = "login_duo"; + source = "${pkgs.duo-unix.out}/bin/login_duo"; + user = "root"; + group = "root"; + setuid = true; + } + ]; + environment.etc = loginCfgFile ++ pamCfgFile; /* If PAM *and* SSH are enabled, then don't do anything special. diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index 77815cd6dcc..4c6b54f0274 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -442,8 +442,25 @@ in ++ optionals config.security.pam.enableU2F [ pkgs.pam_u2f ] ++ optionals config.security.pam.enableEcryptfs [ pkgs.ecryptfs ]; - security.setuidPrograms = - optionals config.security.pam.enableEcryptfs [ "mount.ecryptfs_private" "umount.ecryptfs_private" ]; + security.permissionsWrappers.setuid = + [ + (optionals config.security.pam.enableEcryptfs + { program = "mount.ecryptfs_private" + source = "${pkgs.ecryptfs.out}/bin/mount.ecryptfs_private"; + user = "root"; + group = "root"; + setuid = true; + }) + + (optionals config.security.pam.enableEcryptfs + { program = "umount.ecryptfs_private"; + source = "${pkgs.ecryptfs.out}/bin/umount.ecryptfs_private"; + user = "root"; + group = "root"; + setuid = true; + }) + ] + environment.etc = mapAttrsToList (n: v: makePAMService v) config.security.pam.services; diff --git a/nixos/modules/security/pam_usb.nix b/nixos/modules/security/pam_usb.nix index 11708a1f016..699cf6306e1 100644 --- a/nixos/modules/security/pam_usb.nix +++ b/nixos/modules/security/pam_usb.nix @@ -32,10 +32,25 @@ in config = mkIf (cfg.enable || anyUsbAuth) { - # pmount need to have a set-uid bit to make pam_usb works in user - # environment. (like su, sudo) + # Make sure pmount and pumount are setuid wrapped. + security.permissionsWrappers.setuid = + [ + { program = "pmount"; + source = "${pkgs.pmount.out}/bin/pmount"; + user = "root"; + group = "root"; + setuid = true; + } - security.setuidPrograms = [ "pmount" "pumount" ]; + { program = "pumount"; + source = "${pkgs.pmount.out}/bin/pumount"; + user = "root"; + group = "root"; + setuid = true; + } + ]; + +setuidPrograms = [ "pmount" "pumount" ]; environment.systemPackages = [ pkgs.pmount ]; }; diff --git a/nixos/modules/security/permissions-wrappers/default.nix b/nixos/modules/security/permissions-wrappers/default.nix index a4491946df5..5d4634daf78 100644 --- a/nixos/modules/security/permissions-wrappers/default.nix +++ b/nixos/modules/security/permissions-wrappers/default.nix @@ -43,11 +43,6 @@ let ''; ###### Activation script for the setuid wrappers - setuidPrograms = - (map (x: { program = x; owner = "root"; group = "root"; setuid = true; }) - config.security.setuidPrograms) - ++ config.security.setuidOwners; - makeSetuidWrapper = { program , source ? null diff --git a/nixos/modules/security/polkit.nix b/nixos/modules/security/polkit.nix index 507f81bbf07..db078667acf 100644 --- a/nixos/modules/security/polkit.nix +++ b/nixos/modules/security/polkit.nix @@ -83,7 +83,15 @@ in security.pam.services.polkit-1 = {}; - security.setuidPrograms = [ "pkexec" ]; + security.permissionsWrappers.setuid = + [ + { program = "pkexec"; + source = "${pkgs.polkit.out}/bin/pkexec"; + user = "root"; + group = "root"; + setuid = true; + } + ]; security.setuidOwners = [ { program = "polkit-agent-helper-1"; diff --git a/nixos/modules/security/sudo.nix b/nixos/modules/security/sudo.nix index bced2a6ed75..06dde14cd1c 100644 --- a/nixos/modules/security/sudo.nix +++ b/nixos/modules/security/sudo.nix @@ -81,7 +81,22 @@ in ${cfg.extraConfig} ''; - security.setuidPrograms = [ "sudo" "sudoedit" ]; + security.permissionsWrappers.setuid = + [ + { program = "sudo"; + source = "${pkgs.sudo.out}/bin/sudo"; + user = "root"; + group = "root"; + setuid = true; + } + + { program = "sudoedit" + source = "${pkgs.sudo.out}/bin/sudo"; + user = "root"; + group = "root"; + setuid = true; + } + ]; environment.systemPackages = [ sudo ]; diff --git a/nixos/modules/services/mail/exim.nix b/nixos/modules/services/mail/exim.nix index e0890d96a88..aad497cbc71 100644 --- a/nixos/modules/services/mail/exim.nix +++ b/nixos/modules/services/mail/exim.nix @@ -89,7 +89,15 @@ in gid = config.ids.gids.exim; }; - security.setuidPrograms = [ "exim" ]; + security.permissionsWrappers.setuid = + [ + { program = "exim"; + source = "${pkgs.exim.out}/bin/exim"; + user = "root"; + group = "root"; + setuid = true; + } + ] systemd.services.exim = { description = "Exim Mail Daemon"; diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix index f5e132fd77d..541fbb7ee64 100644 --- a/nixos/modules/services/scheduling/cron.nix +++ b/nixos/modules/services/scheduling/cron.nix @@ -95,7 +95,15 @@ in (mkIf (config.services.cron.enable) { - security.setuidPrograms = [ "crontab" ]; + security.permissionsWrappers.setuid = + [ + { program = "crontab"; + source = "${pkgs.cronNixosPkg.out}/bin/crontab"; + user = "root"; + group = "root"; + setuid = true; + } + ]; environment.systemPackages = [ cronNixosPkg ]; diff --git a/nixos/modules/services/scheduling/fcron.nix b/nixos/modules/services/scheduling/fcron.nix index 7b4665a8204..6e8465ab08f 100644 --- a/nixos/modules/services/scheduling/fcron.nix +++ b/nixos/modules/services/scheduling/fcron.nix @@ -106,7 +106,15 @@ in environment.systemPackages = [ pkgs.fcron ]; - security.setuidPrograms = [ "fcrontab" ]; + security.permissionsWrappers.setuid = + [ + { program = "fcrontab"; + source = "${pkgs.fcron.out}/bin/fcrontab"; + user = "root"; + group = "root"; + setuid = true; + } + ]; systemd.services.fcron = { description = "fcron daemon"; diff --git a/nixos/modules/services/x11/desktop-managers/enlightenment.nix b/nixos/modules/services/x11/desktop-managers/enlightenment.nix index 8a03dd65b33..b55950c6373 100644 --- a/nixos/modules/services/x11/desktop-managers/enlightenment.nix +++ b/nixos/modules/services/x11/desktop-managers/enlightenment.nix @@ -62,7 +62,15 @@ in ''; }]; - security.setuidPrograms = [ "e_freqset" ]; + security.permissionsWrappers.setuid = + [ + { program = "e_freqset"; + source = "${e.enlightenment.out}/bin/e_freqset"; + user = "root"; + group = "root"; + setuid = true; + } + ]; environment.etc = singleton { source = "${pkgs.xkeyboard_config}/etc/X11/xkb"; diff --git a/pkgs/desktops/enlightenment/enlightenment.nix b/pkgs/desktops/enlightenment/enlightenment.nix index f4ff94ad088..979843ffe9c 100644 --- a/pkgs/desktops/enlightenment/enlightenment.nix +++ b/pkgs/desktops/enlightenment/enlightenment.nix @@ -40,13 +40,13 @@ stdenv.mkDerivation rec { # this is a hack and without this cpufreq module is not working. does the following: # 1. moves the "freqset" binary to "e_freqset", # 2. linkes "e_freqset" to enlightenment/bin so that, - # 3. setuidPrograms detects it and makes appropriate stuff to /var/setuid-wrappers/e_freqset, - # 4. and finaly, linkes /var/setuid-wrappers/e_freqset to original destination where enlightenment wants it + # 3. permissionsWrappers.setuid detects it and places wrappers in /var/permissions-wrappers/e_freqset, + # 4. and finally, links /var/permissions-wrappers/e_freqset to original destination where enlightenment wants it postInstall = '' export CPUFREQ_DIRPATH=`readlink -f $out/lib/enlightenment/modules/cpufreq/linux-gnu-*`; mv $CPUFREQ_DIRPATH/freqset $CPUFREQ_DIRPATH/e_freqset ln -sv $CPUFREQ_DIRPATH/e_freqset $out/bin/e_freqset - ln -sv /var/setuid-wrappers/e_freqset $CPUFREQ_DIRPATH/freqset + ln -sv /var/permissions-wrappers/e_freqset $CPUFREQ_DIRPATH/freqset ''; meta = { From 98c058a1ee338731d72d33f320da48c95fecd0e0 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 1 Sep 2016 19:06:21 -0500 Subject: [PATCH 15/74] Adapting everything for the merged permissions wrappers work. --- nixos/modules/config/shells-environment.nix | 2 +- .../modules/installer/tools/nixos-install.sh | 2 +- nixos/modules/programs/kbdlight.nix | 2 +- nixos/modules/programs/light.nix | 2 +- nixos/modules/programs/shadow.nix | 6 +-- nixos/modules/programs/unity3d.nix | 25 ++++++++++ nixos/modules/security/apparmor-suid.nix | 4 +- nixos/modules/security/duosec.nix | 2 +- nixos/modules/security/pam.nix | 45 ++++++++--------- nixos/modules/security/pam_usb.nix | 5 +- .../security/permissions-wrappers/default.nix | 48 +++++++++++-------- .../setcap-wrapper-drv.nix | 6 +-- .../setuid-wrapper-drv.nix | 6 +-- nixos/modules/security/polkit.nix | 18 ++++--- nixos/modules/security/sudo.nix | 8 ++-- nixos/modules/services/logging/logcheck.nix | 4 +- nixos/modules/services/mail/dovecot.nix | 2 +- nixos/modules/services/mail/exim.nix | 6 +-- nixos/modules/services/mail/mail.nix | 2 +- nixos/modules/services/monitoring/munin.nix | 4 +- nixos/modules/services/monitoring/smartd.nix | 2 +- .../services/network-filesystems/samba.nix | 2 +- nixos/modules/services/networking/gale.nix | 2 +- nixos/modules/services/networking/prayer.nix | 2 +- nixos/modules/services/scheduling/atd.nix | 4 +- nixos/modules/services/scheduling/cron.nix | 6 +-- nixos/modules/services/scheduling/fcron.nix | 4 +- nixos/modules/services/system/dbus.nix | 6 +-- .../x11/desktop-managers/enlightenment.nix | 2 +- .../services/x11/desktop-managers/kde4.nix | 2 +- .../services/x11/desktop-managers/kde5.nix | 2 +- .../virtualisation/virtualbox-host.nix | 2 +- .../applications/editors/sublime3/default.nix | 2 +- .../gale/gale-install.in.patch | 2 +- .../wireshark-lookup-dumpcap-in-path.patch | 4 +- .../gitlab/remove-hardcoded-locations.patch | 2 +- .../virtualization/virtualbox/hardened.patch | 6 +-- pkgs/build-support/build-fhs-userenv/env.nix | 2 +- .../development/libraries/libgksu/default.nix | 4 +- pkgs/development/libraries/polkit/default.nix | 2 +- pkgs/development/tools/unity3d/default.nix | 2 +- pkgs/os-specific/linux/fuse/default.nix | 2 +- pkgs/os-specific/linux/mdadm/default.nix | 2 +- pkgs/os-specific/linux/pam/default.nix | 2 +- pkgs/os-specific/linux/util-linux/default.nix | 2 +- pkgs/servers/interlock/default.nix | 2 +- pkgs/servers/mail/petidomo/default.nix | 2 +- .../nagios/plugins/official-2.x.nix | 4 +- pkgs/tools/X11/x11vnc/default.nix | 4 +- pkgs/tools/admin/certbot/default.nix | 2 +- pkgs/tools/misc/debian-devscripts/default.nix | 2 +- pkgs/tools/security/ecryptfs/default.nix | 2 +- pkgs/tools/security/sudo/default.nix | 2 +- pkgs/tools/system/at/default.nix | 2 +- pkgs/tools/system/ts/default.nix | 2 +- 55 files changed, 162 insertions(+), 131 deletions(-) create mode 100644 nixos/modules/programs/unity3d.nix diff --git a/nixos/modules/config/shells-environment.nix b/nixos/modules/config/shells-environment.nix index f458bc39ada..54dd6f6570f 100644 --- a/nixos/modules/config/shells-environment.nix +++ b/nixos/modules/config/shells-environment.nix @@ -169,7 +169,7 @@ in ${cfg.extraInit} # The setuid wrappers override other bin directories. - export PATH="${config.security.wrapperDir}:$PATH" + export PATH="${config.security.permissionsWrapperDir}:$PATH" # ~/bin if it exists overrides other bin directories. export PATH="$HOME/bin:$PATH" diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh index f9412ed444e..27c03ff9792 100644 --- a/nixos/modules/installer/tools/nixos-install.sh +++ b/nixos/modules/installer/tools/nixos-install.sh @@ -262,7 +262,7 @@ chroot $mountPoint /nix/var/nix/profiles/system/activate # Ask the user to set a root password. if [ -z "$noRootPasswd" ] && [ -x $mountPoint/var/setuid-wrappers/passwd ] && [ -t 0 ]; then echo "setting root password..." - chroot $mountPoint /var/setuid-wrappers/passwd + chroot $mountPoint /var/permissions-wrappers/passwd fi diff --git a/nixos/modules/programs/kbdlight.nix b/nixos/modules/programs/kbdlight.nix index c3ea6b5e973..30767a03291 100644 --- a/nixos/modules/programs/kbdlight.nix +++ b/nixos/modules/programs/kbdlight.nix @@ -15,7 +15,7 @@ in security.permissionsWrappers.setuid = [ { program = "kbdlight"; source = "${pkgs.kbdlight.out}/bin/kbdlight"; - user = "root"; + owner = "root"; group = "root"; setuid = true; }]; diff --git a/nixos/modules/programs/light.nix b/nixos/modules/programs/light.nix index d141eaf66f7..c89f8e93721 100644 --- a/nixos/modules/programs/light.nix +++ b/nixos/modules/programs/light.nix @@ -25,7 +25,7 @@ in security.permissionsWrappers.setuid = [ { program = "light"; source = "${pkgs.light.out}/bin/light"; - user = "root"; + owner = "root"; group = "root"; setuid = true; }]; diff --git a/nixos/modules/programs/shadow.nix b/nixos/modules/programs/shadow.nix index 8ee324eaf63..f40faa1ca5f 100644 --- a/nixos/modules/programs/shadow.nix +++ b/nixos/modules/programs/shadow.nix @@ -102,18 +102,18 @@ in chgpasswd = { rootOK = true; }; }; - security.setuidPrograms = + security.permissionsWrappers.setuid = [ { program = "su"; source = "${pkgs.shadow.su}/bin/su"; - user = "root"; + owner = "root"; group = "root"; setuid = true; } { program = "chfn"; source = "${pkgs.shadow.out}/bin/chfn"; - user = "root"; + owner = "root"; group = "root"; setuid = true; } diff --git a/nixos/modules/programs/unity3d.nix b/nixos/modules/programs/unity3d.nix new file mode 100644 index 00000000000..47f1d1ef160 --- /dev/null +++ b/nixos/modules/programs/unity3d.nix @@ -0,0 +1,25 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.programs.unity3d; +in { + + options = { + programs.unity3d.enable = mkEnableOption "Unity3D, a game development tool"; + }; + + config = mkIf cfg.enable { + security.permissionsWrappers.setuid = [{ + program = "unity-chrome-sandbox"; + source = "${pkgs.unity3d.sandbox}/bin/unity-chrome-sandbox"; + owner = "root"; + #group = "root"; + setuid = true; + #setgid = true; + }]; + + environment.systemPackages = [ pkgs.unity3d ]; + }; + +} diff --git a/nixos/modules/security/apparmor-suid.nix b/nixos/modules/security/apparmor-suid.nix index 4a6d61d2676..799f27b6708 100644 --- a/nixos/modules/security/apparmor-suid.nix +++ b/nixos/modules/security/apparmor-suid.nix @@ -19,7 +19,7 @@ with lib; config = mkIf (cfg.confineSUIDApplications) { security.apparmor.profiles = [ (pkgs.writeText "ping" '' #include - /var/setuid-wrappers/ping { + /var/permissions-wrappers/ping { #include #include #include @@ -33,7 +33,7 @@ with lib; ${pkgs.attr.out}/lib/libattr.so* mr, ${pkgs.iputils}/bin/ping mixr, - /var/setuid-wrappers/ping.real r, + /var/permissions-wrappers/ping.real r, #/etc/modules.conf r, diff --git a/nixos/modules/security/duosec.nix b/nixos/modules/security/duosec.nix index 202218c915c..b5e1417fc89 100644 --- a/nixos/modules/security/duosec.nix +++ b/nixos/modules/security/duosec.nix @@ -198,7 +198,7 @@ in [ { program = "login_duo"; source = "${pkgs.duo-unix.out}/bin/login_duo"; - user = "root"; + owner = "root"; group = "root"; setuid = true; } diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index 4c6b54f0274..1c5e6862da6 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -444,34 +444,35 @@ in security.permissionsWrappers.setuid = [ - (optionals config.security.pam.enableEcryptfs - { program = "mount.ecryptfs_private" - source = "${pkgs.ecryptfs.out}/bin/mount.ecryptfs_private"; - user = "root"; - group = "root"; - setuid = true; - }) + { program = "unix_chkpwd"; + source = "${pkgs.pam}/sbin/unix_chkpwd.orig"; + owner = "root"; + group = "root"; + setuid = true; + } + + - (optionals config.security.pam.enableEcryptfs - { program = "umount.ecryptfs_private"; - source = "${pkgs.ecryptfs.out}/bin/umount.ecryptfs_private"; - user = "root"; - group = "root"; - setuid = true; - }) - ] + ] ++ (optional config.security.pam.enableEcryptfs + { program = "umount.ecryptfs_private"; + source = "${pkgs.ecryptfs.out}/bin/umount.ecryptfs_private"; + owner = "root"; + group = "root"; + setuid = true; + } + ) ++ (optional config.security.pam.enableEcryptfs + { program = "mount.ecryptfs_private"; + source = "${pkgs.ecryptfs.out}/bin/mount.ecryptfs_private"; + owner = "root"; + group = "root"; + setuid = true; + } + ); environment.etc = mapAttrsToList (n: v: makePAMService v) config.security.pam.services; - security.setuidOwners = [ { - program = "unix_chkpwd"; - source = "${pkgs.pam}/sbin/unix_chkpwd.orig"; - owner = "root"; - setuid = true; - } ]; - security.pam.services = { other.text = '' diff --git a/nixos/modules/security/pam_usb.nix b/nixos/modules/security/pam_usb.nix index 699cf6306e1..53a7921a244 100644 --- a/nixos/modules/security/pam_usb.nix +++ b/nixos/modules/security/pam_usb.nix @@ -37,20 +37,19 @@ in [ { program = "pmount"; source = "${pkgs.pmount.out}/bin/pmount"; - user = "root"; + owner = "root"; group = "root"; setuid = true; } { program = "pumount"; source = "${pkgs.pmount.out}/bin/pumount"; - user = "root"; + owner = "root"; group = "root"; setuid = true; } ]; -setuidPrograms = [ "pmount" "pumount" ]; environment.systemPackages = [ pkgs.pmount ]; }; diff --git a/nixos/modules/security/permissions-wrappers/default.nix b/nixos/modules/security/permissions-wrappers/default.nix index 5d4634daf78..6b0570faa40 100644 --- a/nixos/modules/security/permissions-wrappers/default.nix +++ b/nixos/modules/security/permissions-wrappers/default.nix @@ -3,10 +3,17 @@ let inherit (config.security) permissionsWrapperDir; + isNotNull = v: if v != null then true else false; + cfg = config.security.permissionsWrappers; - setcapWrappers = import ./setcap-wrapper-drv.nix { }; - setuidWrappers = import ./setuid-wrapper-drv.nix { }; + setcapWrappers = import ./setcap-wrapper-drv.nix { + inherit config lib pkgs; + }; + + setuidWrappers = import ./setuid-wrapper-drv.nix { + inherit config lib pkgs; + }; ###### Activation script for the setcap wrappers configureSetcapWrapper = @@ -16,8 +23,7 @@ let , owner ? "nobody" , group ? "nogroup" , setcap ? false - }: - '' + }: '' cp ${setcapWrappers}/bin/${program}.wrapper ${permissionsWrapperDir}/${program} # Prevent races @@ -43,22 +49,22 @@ let ''; ###### Activation script for the setuid wrappers - makeSetuidWrapper = + configureSetuidWrapper = { program , source ? null , owner ? "nobody" + # Legacy code I can't find :( + , user ? null , group ? "nogroup" , setuid ? false , setgid ? false , permissions ? "u+rx,g+x,o+x" - }: - - '' + }: '' cp ${setuidWrappers}/bin/${program}.wrapper ${permissionsWrapperDir}/${program} # Prevent races chmod 0000 ${permissionsWrapperDir}/${program} - chown ${owner}.${group} ${permissionsWrapperDir}/${program} + chown ${if user != null then user else owner}.${group} ${permissionsWrapperDir}/${program} chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" ${permissionsWrapperDir}/${program} ''; @@ -68,12 +74,12 @@ in ###### interface options = { - security.permissionsWrappers.setcap = mkOption { - type = types.listOf types.attrs; + security.permissionsWrappers.setcap = lib.mkOption { + type = lib.types.listOf lib.types.attrs; default = []; example = [ { program = "ping"; - source = "${pkgs.iputils.out}/bin/ping" + source = "${pkgs.iputils.out}/bin/ping"; owner = "nobody"; group = "nogroup"; setcap = true; @@ -106,12 +112,12 @@ in ''; }; - security.permissionsWrappers.setuid = mkOption { - type = types.listOf types.attrs; + security.permissionsWrappers.setuid = lib.mkOption { + type = lib.types.listOf lib.types.attrs; default = []; example = [ { program = "sendmail"; - source = "${pkgs.sendmail.bin}/bin/sendmail"; + source = "/nix/store/.../bin/sendmail"; owner = "nobody"; group = "postdrop"; setuid = false; @@ -126,8 +132,8 @@ in ''; }; - security.permissionsWrapperDir = mkOption { - type = types.path; + security.permissionsWrapperDir = lib.mkOption { + type = lib.types.path; default = "/var/permissions-wrappers"; internal = true; description = '' @@ -152,7 +158,7 @@ in ###### setcap activation script system.activationScripts.setcap = - stringAfter [ "users" ] + lib.stringAfter [ "users" ] '' # Look in the system path and in the default profile for # programs to be wrapped. @@ -168,12 +174,12 @@ in # Concatenate the generated shell slices to configure # wrappers for each program needing specialized capabilities. - ${concatMapStrings configureSetcapWrapper cfg.setcap} + ${lib.concatMapStrings configureSetcapWrapper (builtins.filter isNotNull cfg.setcap)} ''; ###### setuid activation script system.activationScripts.setuid = - stringAfter [ "users" ] + lib.stringAfter [ "users" ] '' # Look in the system path and in the default profile for # programs to be wrapped. @@ -189,7 +195,7 @@ in # Concatenate the generated shell slices to configure # wrappers for each program needing specialized capabilities. - ${concatMapStrings configureSetuidWrapper cfg.setuid} + ${lib.concatMapStrings configureSetuidWrapper (builtins.filter isNotNull cfg.setuid)} ''; }; diff --git a/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix b/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix index f64c683f6e8..adae9009fbe 100644 --- a/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix +++ b/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix @@ -13,7 +13,7 @@ let source=/nix/var/nix/profiles/default/bin/${program} fi - gcc -Wall -O2 -DWRAPPER_SETCAP=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${cfg.permissionsWrapperDir}\" \ + gcc -Wall -O2 -DWRAPPER_SETCAP=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.permissionsWrapperDir}\" \ -lcap-ng -lcap ${./permissions-wrapper.c} -o $out/bin/${program}.wrapper ''; in @@ -32,6 +32,6 @@ pkgs.stdenv.mkDerivation { # Concat together all of our shell splices to compile # binary wrapper programs for all configured setcap programs. - ${concatMapStrings mkSetcapWrapper cfg.setcap} + ${lib.concatMapStrings mkSetcapWrapper cfg.setcap} ''; -}; +} diff --git a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix b/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix index 15dc1918b5c..e244364aa45 100644 --- a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix +++ b/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix @@ -13,7 +13,7 @@ let source=/nix/var/nix/profiles/default/bin/${program} fi - gcc -Wall -O2 -DWRAPPER_SETUID=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${cfg.permissionsWrapperDir}\" \ + gcc -Wall -O2 -DWRAPPER_SETUID=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.permissionsWrapperDir}\" \ -lcap-ng -lcap ${./permissions-wrapper.c} -o $out/bin/${program}.wrapper ''; in @@ -31,6 +31,6 @@ pkgs.stdenv.mkDerivation { # Concat together all of our shell splices to compile # binary wrapper programs for all configured setcap programs. - ${concatMapStrings mkSetuidWrapper cfg.setuid} + ${lib.concatMapStrings mkSetuidWrapper cfg.setuid} ''; -}; +} diff --git a/nixos/modules/security/polkit.nix b/nixos/modules/security/polkit.nix index db078667acf..098319d5ded 100644 --- a/nixos/modules/security/polkit.nix +++ b/nixos/modules/security/polkit.nix @@ -87,20 +87,18 @@ in [ { program = "pkexec"; source = "${pkgs.polkit.out}/bin/pkexec"; - user = "root"; + owner = "root"; group = "root"; setuid = true; } - ]; - security.setuidOwners = [ - { program = "polkit-agent-helper-1"; - owner = "root"; - group = "root"; - setuid = true; - source = "${pkgs.polkit.out}/lib/polkit-1/polkit-agent-helper-1"; - } - ]; + { program = "polkit-agent-helper-1"; + owner = "root"; + group = "root"; + setuid = true; + source = "${pkgs.polkit.out}/lib/polkit-1/polkit-agent-helper-1"; + } + ]; system.activationScripts.polkit = '' diff --git a/nixos/modules/security/sudo.nix b/nixos/modules/security/sudo.nix index 06dde14cd1c..8a8f1525df4 100644 --- a/nixos/modules/security/sudo.nix +++ b/nixos/modules/security/sudo.nix @@ -85,14 +85,14 @@ in [ { program = "sudo"; source = "${pkgs.sudo.out}/bin/sudo"; - user = "root"; + owner = "root"; group = "root"; setuid = true; } - { program = "sudoedit" - source = "${pkgs.sudo.out}/bin/sudo"; - user = "root"; + { program = "sudoedit"; + source = "${pkgs.sudo.out}/bin/sudoedit"; + owner = "root"; group = "root"; setuid = true; } diff --git a/nixos/modules/services/logging/logcheck.nix b/nixos/modules/services/logging/logcheck.nix index 3a85fa60fe7..755599ff621 100644 --- a/nixos/modules/services/logging/logcheck.nix +++ b/nixos/modules/services/logging/logcheck.nix @@ -29,8 +29,8 @@ let }; cronJob = '' - @reboot logcheck env PATH=/var/setuid-wrappers:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck -R ${flags} - 2 ${cfg.timeOfDay} * * * logcheck env PATH=/var/setuid-wrappers:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck ${flags} + @reboot logcheck env PATH=/var/permissions-wrappers:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck -R ${flags} + 2 ${cfg.timeOfDay} * * * logcheck env PATH=/var/permissions-wrappers:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck ${flags} ''; writeIgnoreRule = name: {level, regex, ...}: diff --git a/nixos/modules/services/mail/dovecot.nix b/nixos/modules/services/mail/dovecot.nix index f239dda564a..7848288850a 100644 --- a/nixos/modules/services/mail/dovecot.nix +++ b/nixos/modules/services/mail/dovecot.nix @@ -13,7 +13,7 @@ let '' base_dir = ${baseDir} protocols = ${concatStringsSep " " cfg.protocols} - sendmail_path = /var/setuid-wrappers/sendmail + sendmail_path = /var/permissions-wrappers/sendmail '' (if isNull cfg.sslServerCert then '' diff --git a/nixos/modules/services/mail/exim.nix b/nixos/modules/services/mail/exim.nix index aad497cbc71..6dfb8fdef11 100644 --- a/nixos/modules/services/mail/exim.nix +++ b/nixos/modules/services/mail/exim.nix @@ -70,7 +70,7 @@ in etc."exim.conf".text = '' exim_user = ${cfg.user} exim_group = ${cfg.group} - exim_path = /var/setuid-wrappers/exim + exim_path = /var/permissions-wrappers/exim spool_directory = ${cfg.spoolDir} ${cfg.config} ''; @@ -93,11 +93,11 @@ in [ { program = "exim"; source = "${pkgs.exim.out}/bin/exim"; - user = "root"; + owner = "root"; group = "root"; setuid = true; } - ] + ]; systemd.services.exim = { description = "Exim Mail Daemon"; diff --git a/nixos/modules/services/mail/mail.nix b/nixos/modules/services/mail/mail.nix index 63e8d78b5b0..e8b16349f1a 100644 --- a/nixos/modules/services/mail/mail.nix +++ b/nixos/modules/services/mail/mail.nix @@ -26,7 +26,7 @@ with lib; config = mkIf (config.services.mail.sendmailSetuidWrapper != null) { - security.setuidOwners = [ config.services.mail.sendmailSetuidWrapper ]; + security.permissionsWrappers.setuid = [ config.services.mail.sendmailSetuidWrapper ]; }; diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix index aaa041ad4cd..08ba161d38b 100644 --- a/nixos/modules/services/monitoring/munin.nix +++ b/nixos/modules/services/monitoring/munin.nix @@ -34,7 +34,7 @@ let cap=$(sed -nr 's/.*#%#\s+capabilities\s*=\s*(.+)/\1/p' $file) wrapProgram $file \ - --set PATH "/var/setuid-wrappers:/run/current-system/sw/bin:/run/current-system/sw/bin" \ + --set PATH "/var/permissions-wrappers:/run/current-system/sw/bin:/run/current-system/sw/bin" \ --set MUNIN_LIBDIR "${pkgs.munin}/lib" \ --set MUNIN_PLUGSTATE "/var/run/munin" @@ -182,7 +182,7 @@ in mkdir -p /etc/munin/plugins rm -rf /etc/munin/plugins/* - PATH="/var/setuid-wrappers:/run/current-system/sw/bin:/run/current-system/sw/bin" ${pkgs.munin}/sbin/munin-node-configure --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${muninPlugins} --servicedir=/etc/munin/plugins 2>/dev/null | ${pkgs.bash}/bin/bash + PATH="/var/permissions-wrappers:/run/current-system/sw/bin:/run/current-system/sw/bin" ${pkgs.munin}/sbin/munin-node-configure --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${muninPlugins} --servicedir=/etc/munin/plugins 2>/dev/null | ${pkgs.bash}/bin/bash ''; serviceConfig = { ExecStart = "${pkgs.munin}/sbin/munin-node --config ${nodeConf} --servicedir /etc/munin/plugins/"; diff --git a/nixos/modules/services/monitoring/smartd.nix b/nixos/modules/services/monitoring/smartd.nix index 1017005226b..b67519b3424 100644 --- a/nixos/modules/services/monitoring/smartd.nix +++ b/nixos/modules/services/monitoring/smartd.nix @@ -124,7 +124,7 @@ in }; mailer = mkOption { - default = "/var/setuid-wrappers/sendmail"; + default = "/var/permissions-wrappers/sendmail"; type = types.path; description = '' Sendmail-compatible binary to be used to send the messages. diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix index a186982ec9c..91f1a333be7 100644 --- a/nixos/modules/services/network-filesystems/samba.nix +++ b/nixos/modules/services/network-filesystems/samba.nix @@ -30,7 +30,7 @@ let '' [ global ] security = ${cfg.securityType} - passwd program = /var/setuid-wrappers/passwd %u + passwd program = /var/permissions-wrappers/passwd %u pam password change = ${smbToString cfg.syncPasswordsByPam} invalid users = ${smbToString cfg.invalidUsers} diff --git a/nixos/modules/services/networking/gale.nix b/nixos/modules/services/networking/gale.nix index bc975159cdf..bc9b884f11b 100644 --- a/nixos/modules/services/networking/gale.nix +++ b/nixos/modules/services/networking/gale.nix @@ -141,7 +141,7 @@ in setgid = false; }; - security.setuidOwners = [ cfg.setuidWrapper ]; + security.permissionsWrappers.setuid = [ cfg.setuidWrapper ]; systemd.services.gale-galed = { description = "Gale messaging daemon"; diff --git a/nixos/modules/services/networking/prayer.nix b/nixos/modules/services/networking/prayer.nix index cb8fe6bf4fe..4e1d66bc110 100644 --- a/nixos/modules/services/networking/prayer.nix +++ b/nixos/modules/services/networking/prayer.nix @@ -18,7 +18,7 @@ let var_prefix = "${stateDir}" prayer_user = "${prayerUser}" prayer_group = "${prayerGroup}" - sendmail_path = "/var/setuid-wrappers/sendmail" + sendmail_path = "/var/permissions-wrappers/sendmail" use_http_port ${cfg.port} diff --git a/nixos/modules/services/scheduling/atd.nix b/nixos/modules/services/scheduling/atd.nix index 2070b2ffa01..9c4f8d59faa 100644 --- a/nixos/modules/services/scheduling/atd.nix +++ b/nixos/modules/services/scheduling/atd.nix @@ -42,8 +42,10 @@ in config = mkIf cfg.enable { - security.setuidOwners = map (program: { + security.permissionsWrappers.setuid = map (program: { inherit program; + + source = "${pkgs.atd}/bin/${program}"; owner = "atd"; group = "atd"; setuid = true; diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix index 541fbb7ee64..e33961658f0 100644 --- a/nixos/modules/services/scheduling/cron.nix +++ b/nixos/modules/services/scheduling/cron.nix @@ -20,7 +20,7 @@ let cronNixosPkg = pkgs.cron.override { # The mail.nix nixos module, if there is any local mail system enabled, # should have sendmail in this path. - sendmailPath = "/var/setuid-wrappers/sendmail"; + sendmailPath = "/var/permissions-wrappers/sendmail"; }; allFiles = @@ -61,7 +61,7 @@ in A list of Cron jobs to be appended to the system-wide crontab. See the manual page for crontab for the expected format. If you want to get the results mailed you must setuid - sendmail. See + sendmail. See If neither /var/cron/cron.deny nor /var/cron/cron.allow exist only root will is allowed to have its own crontab file. The /var/cron/cron.deny file @@ -99,7 +99,7 @@ in [ { program = "crontab"; source = "${pkgs.cronNixosPkg.out}/bin/crontab"; - user = "root"; + owner = "root"; group = "root"; setuid = true; } diff --git a/nixos/modules/services/scheduling/fcron.nix b/nixos/modules/services/scheduling/fcron.nix index 6e8465ab08f..5804f0ee72f 100644 --- a/nixos/modules/services/scheduling/fcron.nix +++ b/nixos/modules/services/scheduling/fcron.nix @@ -96,7 +96,7 @@ in fcronallow = /etc/fcron.allow fcrondeny = /etc/fcron.deny shell = /bin/sh - sendmail = /var/setuid-wrappers/sendmail + sendmail = /var/permissions-wrappers/sendmail editor = /run/current-system/sw/bin/vi ''; target = "fcron.conf"; @@ -110,7 +110,7 @@ in [ { program = "fcrontab"; source = "${pkgs.fcron.out}/bin/fcrontab"; - user = "root"; + owner = "root"; group = "root"; setuid = true; } diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix index 8bcd6f01656..df93fcd2bdb 100644 --- a/nixos/modules/services/system/dbus.nix +++ b/nixos/modules/services/system/dbus.nix @@ -30,7 +30,7 @@ let mkdir -p $out sed '${./dbus-system-local.conf.in}' \ - -e 's,@servicehelper@,${config.security.wrapperDir}/dbus-daemon-launch-helper,g' \ + -e 's,@servicehelper@,${config.security.permissionsWrapperDir}/dbus-daemon-launch-helper,g' \ -e 's,@extra@,${systemExtraxml},' \ > "$out/system-local.conf" @@ -102,9 +102,9 @@ in systemd.packages = [ pkgs.dbus.daemon ]; - security.setuidOwners = singleton + security.permissionsWrappers.setuid = singleton { program = "dbus-daemon-launch-helper"; - source = "${pkgs.dbus_daemon.out}/libexec/dbus-daemon-launch-helper"; + source = "${pkgs.dbus_daemon}/libexec/dbus-daemon-launch-helper"; owner = "root"; group = "messagebus"; setuid = true; diff --git a/nixos/modules/services/x11/desktop-managers/enlightenment.nix b/nixos/modules/services/x11/desktop-managers/enlightenment.nix index b55950c6373..90803ede9d9 100644 --- a/nixos/modules/services/x11/desktop-managers/enlightenment.nix +++ b/nixos/modules/services/x11/desktop-managers/enlightenment.nix @@ -66,7 +66,7 @@ in [ { program = "e_freqset"; source = "${e.enlightenment.out}/bin/e_freqset"; - user = "root"; + owner = "root"; group = "root"; setuid = true; } diff --git a/nixos/modules/services/x11/desktop-managers/kde4.nix b/nixos/modules/services/x11/desktop-managers/kde4.nix index 1927341e45d..88b3c3a1016 100644 --- a/nixos/modules/services/x11/desktop-managers/kde4.nix +++ b/nixos/modules/services/x11/desktop-managers/kde4.nix @@ -119,7 +119,7 @@ in ''; }; - security.setuidOwners = singleton + security.permissionsWrappers.setuid = singleton { program = "kcheckpass"; source = "${kde_workspace}/lib/kde4/libexec/kcheckpass"; owner = "root"; diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix index bc010d1ce1c..7856ff03f16 100644 --- a/nixos/modules/services/x11/desktop-managers/kde5.nix +++ b/nixos/modules/services/x11/desktop-managers/kde5.nix @@ -47,7 +47,7 @@ in ''; }; - security.setuidOwners = [ + security.permissionsWrappers.setuid = [ { program = "kcheckpass"; source = "${kde5.plasma-workspace.out}/lib/libexec/kcheckpass"; diff --git a/nixos/modules/virtualisation/virtualbox-host.nix b/nixos/modules/virtualisation/virtualbox-host.nix index ce4abecd676..ee8569d3c0c 100644 --- a/nixos/modules/virtualisation/virtualbox-host.nix +++ b/nixos/modules/virtualisation/virtualbox-host.nix @@ -63,7 +63,7 @@ in boot.extraModulePackages = [ virtualbox ]; environment.systemPackages = [ virtualbox ]; - security.setuidOwners = let + security.permissionsWrappers.setuid = let mkSuid = program: { inherit program; source = "${virtualbox}/libexec/virtualbox/${program}"; diff --git a/pkgs/applications/editors/sublime3/default.nix b/pkgs/applications/editors/sublime3/default.nix index 4eb428f37d8..9e7b52e40d4 100644 --- a/pkgs/applications/editors/sublime3/default.nix +++ b/pkgs/applications/editors/sublime3/default.nix @@ -1,5 +1,5 @@ { fetchurl, stdenv, glib, xorg, cairo, gtk, pango, makeWrapper, openssl, bzip2, - pkexecPath ? "/var/setuid-wrappers/pkexec", libredirect, + pkexecPath ? "/var/permissions-wrappers/pkexec", libredirect, gksuSupport ? false, gksu}: assert stdenv.system == "i686-linux" || stdenv.system == "x86_64-linux"; diff --git a/pkgs/applications/networking/instant-messengers/gale/gale-install.in.patch b/pkgs/applications/networking/instant-messengers/gale/gale-install.in.patch index f9c3e3c5592..9a83fc09e4e 100644 --- a/pkgs/applications/networking/instant-messengers/gale/gale-install.in.patch +++ b/pkgs/applications/networking/instant-messengers/gale/gale-install.in.patch @@ -26,7 +26,7 @@ index 50e8ad8..eec0ed2 100644 + is_nixos=no +fi + -+if [ -u /var/setuid-wrappers/gksign ]; then ++if [ -u /var/permissions-wrappers/gksign ]; then + cat </dev/null") == 0) { diff --git a/pkgs/applications/version-management/gitlab/remove-hardcoded-locations.patch b/pkgs/applications/version-management/gitlab/remove-hardcoded-locations.patch index a8a0542a882..fb5b9e1d39d 100644 --- a/pkgs/applications/version-management/gitlab/remove-hardcoded-locations.patch +++ b/pkgs/applications/version-management/gitlab/remove-hardcoded-locations.patch @@ -11,7 +11,7 @@ index a9d8ac4..85f13f5 100644 - # # arguments: '-i -t' - # # } + config.action_mailer.sendmail_settings = { -+ location: '/var/setuid-wrappers/sendmail', ++ location: '/var/permissions-wrappers/sendmail', + arguments: '-i -t' + } config.action_mailer.perform_deliveries = true diff --git a/pkgs/applications/virtualization/virtualbox/hardened.patch b/pkgs/applications/virtualization/virtualbox/hardened.patch index 37d2ad3a515..cae4abe8612 100644 --- a/pkgs/applications/virtualization/virtualbox/hardened.patch +++ b/pkgs/applications/virtualization/virtualbox/hardened.patch @@ -96,7 +96,7 @@ index 95dc9a7..39170bc 100644 /* get the path to the executable */ char szPath[RTPATH_MAX]; - RTPathAppPrivateArch(szPath, sizeof(szPath) - 1); -+ RTStrCopy(szPath, sizeof(szPath) - 1, "/var/setuid-wrappers"); ++ RTStrCopy(szPath, sizeof(szPath) - 1, "/var/permissions-wrappers"); size_t cchBufLeft = strlen(szPath); szPath[cchBufLeft++] = RTPATH_DELIMITER; szPath[cchBufLeft] = 0; @@ -154,7 +154,7 @@ index be2ad8f..7ddf105 100644 +RTDECL(int) RTPathSuidDir(char *pszPath, size_t cchPath) +{ -+ return RTStrCopy(pszPath, cchPath, "/var/setuid-wrappers"); ++ return RTStrCopy(pszPath, cchPath, "/var/permissions-wrappers"); +} + + @@ -174,7 +174,7 @@ index 7bde6af..2656cae 100644 + * will cut off everything after the rightmost / as this function is analogous + * to RTProcGetExecutablePath(). + */ -+#define SUIDDIR "/var/setuid-wrappers/" ++#define SUIDDIR "/var/permissions-wrappers/" + +RTR3DECL(char *) RTProcGetSuidPath(char *pszExecPath, size_t cbExecPath) +{ diff --git a/pkgs/build-support/build-fhs-userenv/env.nix b/pkgs/build-support/build-fhs-userenv/env.nix index 1dc71987f54..f69338cb16c 100644 --- a/pkgs/build-support/build-fhs-userenv/env.nix +++ b/pkgs/build-support/build-fhs-userenv/env.nix @@ -51,7 +51,7 @@ let export PS1='${name}-chrootenv:\u@\h:\w\$ ' export LOCALE_ARCHIVE='/usr/lib/locale/locale-archive' export LD_LIBRARY_PATH='/run/opengl-driver/lib:/run/opengl-driver-32/lib:/usr/lib:/usr/lib32' - export PATH='/var/setuid-wrappers:/usr/bin:/usr/sbin' + export PATH='/var/permissions-wrappers:/usr/bin:/usr/sbin' export PKG_CONFIG_PATH=/usr/lib/pkgconfig # Force compilers to look in default search paths diff --git a/pkgs/development/libraries/libgksu/default.nix b/pkgs/development/libraries/libgksu/default.nix index b86eba685bb..4cedd6f8e8f 100644 --- a/pkgs/development/libraries/libgksu/default.nix +++ b/pkgs/development/libraries/libgksu/default.nix @@ -57,8 +57,8 @@ stdenv.mkDerivation rec { # Fix some binary paths sed -i -e 's|/usr/bin/xauth|${xauth}/bin/xauth|g' libgksu/gksu-run-helper.c libgksu/libgksu.c - sed -i -e 's|/usr/bin/sudo|/var/setuid-wrappers/sudo|g' libgksu/libgksu.c - sed -i -e 's|/bin/su\([^d]\)|/var/setuid-wrappers/su\1|g' libgksu/libgksu.c + sed -i -e 's|/usr/bin/sudo|/var/permissions-wrappers/sudo|g' libgksu/libgksu.c + sed -i -e 's|/bin/su\([^d]\)|/var/permissions-wrappers/su\1|g' libgksu/libgksu.c touch NEWS README ''; diff --git a/pkgs/development/libraries/polkit/default.nix b/pkgs/development/libraries/polkit/default.nix index ab1943b8590..f33ee3917f1 100644 --- a/pkgs/development/libraries/polkit/default.nix +++ b/pkgs/development/libraries/polkit/default.nix @@ -5,7 +5,7 @@ let system = "/var/run/current-system/sw"; - setuid = "/var/setuid-wrappers"; #TODO: from config.security.wrapperDir; + setuid = "/var/permissions-wrappers"; #TODO: from config.security.wrapperDir; foolVars = { SYSCONF = "/etc"; diff --git a/pkgs/development/tools/unity3d/default.nix b/pkgs/development/tools/unity3d/default.nix index 0a72e6bb91e..287422282cb 100644 --- a/pkgs/development/tools/unity3d/default.nix +++ b/pkgs/development/tools/unity3d/default.nix @@ -94,7 +94,7 @@ in stdenv.mkDerivation rec { unitydir="$out/opt/Unity/Editor" mkdir -p $unitydir mv Editor/* $unitydir - ln -sf /var/setuid-wrappers/${chromium.sandboxExecutableName} $unitydir/chrome-sandbox + ln -sf /var/permissions-wrappers/${chromium.sandboxExecutableName} $unitydir/chrome-sandbox mkdir -p $out/share/applications sed "/^Exec=/c\Exec=$out/bin/unity-editor" \ diff --git a/pkgs/os-specific/linux/fuse/default.nix b/pkgs/os-specific/linux/fuse/default.nix index d86eb2a9756..9f63ae4f35a 100644 --- a/pkgs/os-specific/linux/fuse/default.nix +++ b/pkgs/os-specific/linux/fuse/default.nix @@ -23,7 +23,7 @@ stdenv.mkDerivation rec { # Ensure that FUSE calls the setuid wrapper, not # $out/bin/fusermount. It falls back to calling fusermount in # $PATH, so it should also work on non-NixOS systems. - export NIX_CFLAGS_COMPILE="-DFUSERMOUNT_DIR=\"/var/setuid-wrappers\"" + export NIX_CFLAGS_COMPILE="-DFUSERMOUNT_DIR=\"/var/permissions-wrappers\"" sed -e 's@/bin/@${utillinux}/bin/@g' -i lib/mount_util.c ''; diff --git a/pkgs/os-specific/linux/mdadm/default.nix b/pkgs/os-specific/linux/mdadm/default.nix index 3fa7e2ba8d1..531d55a7f12 100644 --- a/pkgs/os-specific/linux/mdadm/default.nix +++ b/pkgs/os-specific/linux/mdadm/default.nix @@ -31,7 +31,7 @@ stdenv.mkDerivation rec { preConfigure = '' sed -e 's@/lib/udev@''${out}/lib/udev@' \ -e 's@ -Werror @ @' \ - -e 's@/usr/sbin/sendmail@/var/setuid-wrappers/sendmail@' -i Makefile + -e 's@/usr/sbin/sendmail@/var/permissions-wrappers/sendmail@' -i Makefile ''; meta = { diff --git a/pkgs/os-specific/linux/pam/default.nix b/pkgs/os-specific/linux/pam/default.nix index d84c6224eeb..196af58183f 100644 --- a/pkgs/os-specific/linux/pam/default.nix +++ b/pkgs/os-specific/linux/pam/default.nix @@ -34,7 +34,7 @@ stdenv.mkDerivation rec { postInstall = '' mv -v $out/sbin/unix_chkpwd{,.orig} - ln -sv /var/setuid-wrappers/unix_chkpwd $out/sbin/unix_chkpwd + ln -sv /var/permissions-wrappers/unix_chkpwd $out/sbin/unix_chkpwd ''; /* rm -rf $out/etc mkdir -p $modules/lib diff --git a/pkgs/os-specific/linux/util-linux/default.nix b/pkgs/os-specific/linux/util-linux/default.nix index 4d4a22fc720..11444c57f9a 100644 --- a/pkgs/os-specific/linux/util-linux/default.nix +++ b/pkgs/os-specific/linux/util-linux/default.nix @@ -43,7 +43,7 @@ stdenv.mkDerivation rec { --enable-last --enable-mesg --disable-use-tty-group - --enable-fs-paths-default=/var/setuid-wrappers:/var/run/current-system/sw/bin:/sbin + --enable-fs-paths-default=/var/permissions-wrappers:/var/run/current-system/sw/bin:/sbin ${if ncurses == null then "--without-ncurses" else ""} ${if systemd == null then "" else '' --with-systemd diff --git a/pkgs/servers/interlock/default.nix b/pkgs/servers/interlock/default.nix index 5842495e323..d3c143617dd 100644 --- a/pkgs/servers/interlock/default.nix +++ b/pkgs/servers/interlock/default.nix @@ -30,7 +30,7 @@ buildGoPackage rec { -e 's|/bin/chown|${coreutils}/bin/chown|' \ -e 's|/bin/date|${coreutils}/bin/date|' \ -e 's|/sbin/poweroff|${systemd}/sbin/poweroff|' \ - -e 's|/usr/bin/sudo|/var/setuid-wrappers/sudo|' \ + -e 's|/usr/bin/sudo|/var/permissions-wrappers/sudo|' \ -e 's|/sbin/cryptsetup|${cryptsetup}/bin/cryptsetup|' ''; } diff --git a/pkgs/servers/mail/petidomo/default.nix b/pkgs/servers/mail/petidomo/default.nix index 3ecb00b64fc..c112af567fd 100644 --- a/pkgs/servers/mail/petidomo/default.nix +++ b/pkgs/servers/mail/petidomo/default.nix @@ -1,4 +1,4 @@ -{ stdenv, fetchurl, flex, bison, sendmailPath ? "/var/setuid-wrappers/sendmail" }: +{ stdenv, fetchurl, flex, bison, sendmailPath ? "/var/permissions-wrappers/sendmail" }: stdenv.mkDerivation rec { name = "petidomo-4.3"; diff --git a/pkgs/servers/monitoring/nagios/plugins/official-2.x.nix b/pkgs/servers/monitoring/nagios/plugins/official-2.x.nix index 79180f17241..695211a177d 100644 --- a/pkgs/servers/monitoring/nagios/plugins/official-2.x.nix +++ b/pkgs/servers/monitoring/nagios/plugins/official-2.x.nix @@ -16,8 +16,8 @@ stdenv.mkDerivation rec { # configured on the build machine). preConfigure= " configureFlagsArray=( - --with-ping-command='/var/setuid-wrappers/ping -n -U -w %d -c %d %s' - --with-ping6-command='/var/setuid-wrappers/ping6 -n -U -w %d -c %d %s' + --with-ping-command='/var/permissions-wrappers/ping -n -U -w %d -c %d %s' + --with-ping6-command='/var/permissions-wrappers/ping6 -n -U -w %d -c %d %s' ) "; diff --git a/pkgs/tools/X11/x11vnc/default.nix b/pkgs/tools/X11/x11vnc/default.nix index a8c249116c0..5f96a35af6f 100644 --- a/pkgs/tools/X11/x11vnc/default.nix +++ b/pkgs/tools/X11/x11vnc/default.nix @@ -20,10 +20,10 @@ stdenv.mkDerivation rec { configureFlags="--mandir=$out/share/man" substituteInPlace x11vnc/unixpw.c \ - --replace '"/bin/su"' '"/var/setuid-wrappers/su"' \ + --replace '"/bin/su"' '"/var/permissions-wrappers/su"' \ --replace '"/bin/true"' '"${coreutils}/bin/true"' - sed -i -e '/#!\/bin\/sh/a"PATH=${xorg.xdpyinfo}\/bin:${xorg.xauth}\/bin:$PATH\\n"' -e 's|/bin/su|/var/setuid-wrappers/su|g' x11vnc/ssltools.h + sed -i -e '/#!\/bin\/sh/a"PATH=${xorg.xdpyinfo}\/bin:${xorg.xauth}\/bin:$PATH\\n"' -e 's|/bin/su|/var/permissions-wrappers/su|g' x11vnc/ssltools.h ''; meta = { diff --git a/pkgs/tools/admin/certbot/default.nix b/pkgs/tools/admin/certbot/default.nix index 80805666a3a..518c3763994 100644 --- a/pkgs/tools/admin/certbot/default.nix +++ b/pkgs/tools/admin/certbot/default.nix @@ -29,7 +29,7 @@ pythonPackages.buildPythonApplication rec { buildInputs = [ dialog ] ++ (with pythonPackages; [ nose mock gnureadline ]); patchPhase = '' - substituteInPlace certbot/notify.py --replace "/usr/sbin/sendmail" "/var/setuid-wrappers/sendmail" + substituteInPlace certbot/notify.py --replace "/usr/sbin/sendmail" "/var/permissions-wrappers/sendmail" substituteInPlace certbot/le_util.py --replace "sw_vers" "/usr/bin/sw_vers" ''; diff --git a/pkgs/tools/misc/debian-devscripts/default.nix b/pkgs/tools/misc/debian-devscripts/default.nix index ece9c5ed382..15108852fbc 100644 --- a/pkgs/tools/misc/debian-devscripts/default.nix +++ b/pkgs/tools/misc/debian-devscripts/default.nix @@ -2,7 +2,7 @@ , FileDesktopEntry, libxslt, docbook_xsl, makeWrapper , python3Packages , perlPackages, curl, gnupg, diffutils -, sendmailPath ? "/var/setuid-wrappers/sendmail" +, sendmailPath ? "/var/permissions-wrappers/sendmail" }: let diff --git a/pkgs/tools/security/ecryptfs/default.nix b/pkgs/tools/security/ecryptfs/default.nix index 582b5ceae11..a477b22f191 100644 --- a/pkgs/tools/security/ecryptfs/default.nix +++ b/pkgs/tools/security/ecryptfs/default.nix @@ -11,7 +11,7 @@ stdenv.mkDerivation rec { }; # TODO: replace wrapperDir below with from config.security.wrapperDir; - wrapperDir = "/var/setuid-wrappers"; + wrapperDir = "/var/permissions-wrappers"; postPatch = '' FILES="$(grep -r '/bin/sh' src/utils -l; find src -name \*.c)" diff --git a/pkgs/tools/security/sudo/default.nix b/pkgs/tools/security/sudo/default.nix index e2c69377df5..b0b19d750eb 100644 --- a/pkgs/tools/security/sudo/default.nix +++ b/pkgs/tools/security/sudo/default.nix @@ -1,5 +1,5 @@ { stdenv, fetchurl, coreutils, pam, groff -, sendmailPath ? "/var/setuid-wrappers/sendmail" +, sendmailPath ? "/var/permissions-wrappers/sendmail" , withInsults ? false }: diff --git a/pkgs/tools/system/at/default.nix b/pkgs/tools/system/at/default.nix index 9991adf4013..2fb5b9670c8 100644 --- a/pkgs/tools/system/at/default.nix +++ b/pkgs/tools/system/at/default.nix @@ -1,4 +1,4 @@ -{ fetchurl, stdenv, bison, flex, pam, sendmailPath ? "/var/setuid-wrappers/sendmail" }: +{ fetchurl, stdenv, bison, flex, pam, sendmailPath ? "/var/permissions-wrappers/sendmail" }: stdenv.mkDerivation { name = "at-3.1.16"; diff --git a/pkgs/tools/system/ts/default.nix b/pkgs/tools/system/ts/default.nix index cad1230ac87..1384ea04fb6 100644 --- a/pkgs/tools/system/ts/default.nix +++ b/pkgs/tools/system/ts/default.nix @@ -1,5 +1,5 @@ {stdenv, fetchurl, -sendmailPath ? "/var/setuid-wrappers/sendmail" }: +sendmailPath ? "/var/permissions-wrappers/sendmail" }: stdenv.mkDerivation rec { From 849dcde2a53398f91ab1da9adedcf65616c4e6ef Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 1 Sep 2016 19:22:37 -0500 Subject: [PATCH 16/74] Wonder why this wasn't removed in the rebase? --- nixos/modules/programs/unity3d.nix | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 nixos/modules/programs/unity3d.nix diff --git a/nixos/modules/programs/unity3d.nix b/nixos/modules/programs/unity3d.nix deleted file mode 100644 index 47f1d1ef160..00000000000 --- a/nixos/modules/programs/unity3d.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let cfg = config.programs.unity3d; -in { - - options = { - programs.unity3d.enable = mkEnableOption "Unity3D, a game development tool"; - }; - - config = mkIf cfg.enable { - security.permissionsWrappers.setuid = [{ - program = "unity-chrome-sandbox"; - source = "${pkgs.unity3d.sandbox}/bin/unity-chrome-sandbox"; - owner = "root"; - #group = "root"; - setuid = true; - #setgid = true; - }]; - - environment.systemPackages = [ pkgs.unity3d ]; - }; - -} From c686da8655bbdd4f0677bea788794e7b9f1d7dda Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 1 Sep 2016 19:26:30 -0500 Subject: [PATCH 17/74] Updatig the chromium-suid-sandbox module --- nixos/modules/security/chromium-suid-sandbox.nix | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nixos/modules/security/chromium-suid-sandbox.nix b/nixos/modules/security/chromium-suid-sandbox.nix index 88fbe518c2d..6fe25213639 100644 --- a/nixos/modules/security/chromium-suid-sandbox.nix +++ b/nixos/modules/security/chromium-suid-sandbox.nix @@ -27,6 +27,10 @@ in config = mkIf cfg.enable { environment.systemPackages = [ sandbox ]; - security.setuidPrograms = [ sandbox.passthru.sandboxExecutableName ]; + security.permissionsWrappers.setuid = [ + { program = sandbox.passthru.sandboxExecutableName; + source = "${sandbox}/bin/${sandbox.passthru.sandboxExecutableName}"; + } + ]; }; } From d60581d4d620787311e4268354680025eaeec27a Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 1 Sep 2016 19:26:54 -0500 Subject: [PATCH 18/74] Resolving that silly bad argument error. --- nixos/modules/programs/shadow.nix | 2 +- nixos/modules/security/permissions-wrappers/default.nix | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/nixos/modules/programs/shadow.nix b/nixos/modules/programs/shadow.nix index f40faa1ca5f..3910831fb0e 100644 --- a/nixos/modules/programs/shadow.nix +++ b/nixos/modules/programs/shadow.nix @@ -119,7 +119,7 @@ in } ] ++ (lib.optionals config.users.mutableUsers - map (x: x // { user = "root"; + map (x: x // { owner = "root"; group = "root"; setuid = true; }) diff --git a/nixos/modules/security/permissions-wrappers/default.nix b/nixos/modules/security/permissions-wrappers/default.nix index 6b0570faa40..76a22b4f603 100644 --- a/nixos/modules/security/permissions-wrappers/default.nix +++ b/nixos/modules/security/permissions-wrappers/default.nix @@ -53,8 +53,6 @@ let { program , source ? null , owner ? "nobody" - # Legacy code I can't find :( - , user ? null , group ? "nogroup" , setuid ? false , setgid ? false @@ -64,7 +62,7 @@ let # Prevent races chmod 0000 ${permissionsWrapperDir}/${program} - chown ${if user != null then user else owner}.${group} ${permissionsWrapperDir}/${program} + chown ${owner}.${group} ${permissionsWrapperDir}/${program} chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" ${permissionsWrapperDir}/${program} ''; From 1f9494b752082ec3ac048e56d1c6364a2e23a675 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 1 Sep 2016 19:47:41 -0500 Subject: [PATCH 19/74] Need to create a new build to see why it's failing --- nixos/modules/programs/shadow.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nixos/modules/programs/shadow.nix b/nixos/modules/programs/shadow.nix index 3910831fb0e..f6f66924f32 100644 --- a/nixos/modules/programs/shadow.nix +++ b/nixos/modules/programs/shadow.nix @@ -102,6 +102,7 @@ in chgpasswd = { rootOK = true; }; }; + security.permissionsWrappers.setuid = [ { program = "su"; From 025555d7f1a0fc39ea152b03e942002e1bff1721 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 00:05:40 -0800 Subject: [PATCH 20/74] More fixes and improvements --- nixos/doc/manual/release-notes/rl-1609.xml | 2 +- .../modules/installer/tools/nixos-install.sh | 2 +- .../security/permissions-wrappers/default.nix | 4 ++++ .../setcap-wrapper-drv.nix | 22 +++++++++---------- .../setuid-wrapper-drv.nix | 5 +++-- .../modules/services/networking/smokeping.nix | 13 ++++++++--- nixos/tests/smokeping.nix | 2 +- .../networking/browsers/chromium/default.nix | 4 ++-- .../kinit/start_kdeinit-path.patch | 2 +- pkgs/os-specific/linux/mdadm/4.nix | 2 +- pkgs/tools/security/ecryptfs/helper.nix | 2 +- pkgs/tools/system/cron/default.nix | 2 +- 12 files changed, 37 insertions(+), 25 deletions(-) diff --git a/nixos/doc/manual/release-notes/rl-1609.xml b/nixos/doc/manual/release-notes/rl-1609.xml index ade7d5581ce..bf8be1b68f2 100644 --- a/nixos/doc/manual/release-notes/rl-1609.xml +++ b/nixos/doc/manual/release-notes/rl-1609.xml @@ -202,7 +202,7 @@ following incompatible changes: The directory container setuid wrapper programs, - /var/setuid-wrappers, /var/permissions-wrappers, is now updated atomically to prevent failures if the switch to a new configuration is interrupted. diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh index 5250edd1500..4e9f8ab60f2 100644 --- a/nixos/modules/installer/tools/nixos-install.sh +++ b/nixos/modules/installer/tools/nixos-install.sh @@ -260,7 +260,7 @@ chroot $mountPoint /nix/var/nix/profiles/system/activate # Ask the user to set a root password. -if [ -z "$noRootPasswd" ] && chroot $mountPoint [ -x /var/setuid-wrappers/passwd ] && [ -t 0 ]; then +if [ -z "$noRootPasswd" ] && chroot $mountPoint [ -x /var/permissions-wrappers/passwd ] && [ -t 0 ]; then echo "setting root password..." chroot $mountPoint /var/permissions-wrappers/passwd fi diff --git a/nixos/modules/security/permissions-wrappers/default.nix b/nixos/modules/security/permissions-wrappers/default.nix index 76a22b4f603..2f60d54fd77 100644 --- a/nixos/modules/security/permissions-wrappers/default.nix +++ b/nixos/modules/security/permissions-wrappers/default.nix @@ -154,6 +154,10 @@ in export PATH="${config.security.permissionsWrapperDir}:$PATH" ''; + system.activationScripts.wrapper-dir = '' + mkdir -p "${config.security.permissionsWrapperDir}" + ''; + ###### setcap activation script system.activationScripts.setcap = lib.stringAfter [ "users" ] diff --git a/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix b/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix index adae9009fbe..04cae3c8493 100644 --- a/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix +++ b/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix @@ -5,17 +5,17 @@ let # Produce a shell-code splice intended to be stitched into one of # the build or install phases within the derivation. - mkSetcapWrapper = { program, source ? null, ...}: - '' - if ! source=${if source != null then source else "$(readlink -f $(PATH=$PERMISSIONS_WRAPPER_PATH type -tP ${program}))"}; then - # If we can't find the program, fall back to the - # system profile. - source=/nix/var/nix/profiles/default/bin/${program} - fi + mkSetcapWrapper = { program, source ? null, ...}: '' + if ! source=${if source != null then source else "$(readlink -f $(PATH=$PERMISSIONS_WRAPPER_PATH type -tP ${program}))"}; then + # If we can't find the program, fall back to the + # system profile. + source=/nix/var/nix/profiles/default/bin/${program} + fi - gcc -Wall -O2 -DWRAPPER_SETCAP=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.permissionsWrapperDir}\" \ - -lcap-ng -lcap ${./permissions-wrapper.c} -o $out/bin/${program}.wrapper - ''; + gcc -Wall -O2 -DWRAPPER_SETCAP=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.permissionsWrapperDir}\" \ + -lcap-ng -lcap ${./permissions-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 # This is only useful for Linux platforms and a kernel version of @@ -26,7 +26,7 @@ assert lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4. pkgs.stdenv.mkDerivation { name = "setcap-wrapper"; unpackPhase = "true"; - buildInputs = [ pkgs.linuxHeaders pkgs.libcap pkgs.libcap_ng ]; + buildInputs = [ pkgs.linuxHeaders ]; installPhase = '' mkdir -p $out/bin diff --git a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix b/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix index e244364aa45..273aaf2a88a 100644 --- a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix +++ b/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix @@ -13,8 +13,9 @@ let source=/nix/var/nix/profiles/default/bin/${program} fi - gcc -Wall -O2 -DWRAPPER_SETUID=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.permissionsWrapperDir}\" \ - -lcap-ng -lcap ${./permissions-wrapper.c} -o $out/bin/${program}.wrapper + gcc -Wall -O2 -DWRAPPER_SETCAP=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.permissionsWrapperDir}\" \ + -lcap-ng -lcap ${./permissions-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 diff --git a/nixos/modules/services/networking/smokeping.nix b/nixos/modules/services/networking/smokeping.nix index 04312c39062..6d2f5f8d41f 100644 --- a/nixos/modules/services/networking/smokeping.nix +++ b/nixos/modules/services/networking/smokeping.nix @@ -219,14 +219,14 @@ in type = types.string; default = '' + FPing - binary = ${config.security.wrapperDir}/fping + binary = ${config.security.permissionsWrapperDir}/fping ''; description = "Probe configuration"; }; sendmail = mkOption { type = types.nullOr types.path; default = null; - example = "/var/setuid-wrappers/sendmail"; + example = "/var/permissions-wrappers/sendmail"; description = "Use this sendmail compatible script to deliver alerts"; }; smokeMailTemplate = mkOption { @@ -273,7 +273,14 @@ in message = "services.smokeping: sendmail and Mailhost cannot both be enabled."; } ]; - security.setuidPrograms = [ "fping" ]; + security.permissionsWrappers.setuid = [ + { program = "fping"; + source = "${e.enlightenment.out}/bin/fping"; + owner = "root"; + group = "root"; + setuid = true; + } + ]; environment.systemPackages = [ pkgs.fping ]; users.extraUsers = singleton { name = cfg.user; diff --git a/nixos/tests/smokeping.nix b/nixos/tests/smokeping.nix index 9de3030417f..7e2d84f4422 100644 --- a/nixos/tests/smokeping.nix +++ b/nixos/tests/smokeping.nix @@ -14,7 +14,7 @@ import ./make-test.nix ({ pkgs, ...} : { mailHost = "127.0.0.2"; probeConfig = '' + FPing - binary = /var/setuid-wrappers/fping + binary = /var/permissions-wrappers/fping offset = 0% ''; }; diff --git a/pkgs/applications/networking/browsers/chromium/default.nix b/pkgs/applications/networking/browsers/chromium/default.nix index d014999a667..dd8fd32adfd 100644 --- a/pkgs/applications/networking/browsers/chromium/default.nix +++ b/pkgs/applications/networking/browsers/chromium/default.nix @@ -83,9 +83,9 @@ in stdenv.mkDerivation { ed -v -s "$out/bin/chromium" << EOF 2i - if [ -x "/var/setuid-wrappers/${sandboxExecutableName}" ] + if [ -x "/var/permissions-wrappers/${sandboxExecutableName}" ] then - export CHROME_DEVEL_SANDBOX="/var/setuid-wrappers/${sandboxExecutableName}" + export CHROME_DEVEL_SANDBOX="/var/permissions-wrappers/${sandboxExecutableName}" else export CHROME_DEVEL_SANDBOX="$sandbox/bin/${sandboxExecutableName}" fi diff --git a/pkgs/development/libraries/kde-frameworks/kinit/start_kdeinit-path.patch b/pkgs/development/libraries/kde-frameworks/kinit/start_kdeinit-path.patch index fbecf9433f6..a16d3575725 100644 --- a/pkgs/development/libraries/kde-frameworks/kinit/start_kdeinit-path.patch +++ b/pkgs/development/libraries/kde-frameworks/kinit/start_kdeinit-path.patch @@ -7,7 +7,7 @@ Index: kinit-5.24.0/src/start_kdeinit/start_kdeinit_wrapper.c #include -#define EXECUTE CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/start_kdeinit" -+#define EXECUTE "/var/setuid-wrappers/start_kdeinit" ++#define EXECUTE "/var/permissions-wrappers/start_kdeinit" #if KDEINIT_OOM_PROTECT diff --git a/pkgs/os-specific/linux/mdadm/4.nix b/pkgs/os-specific/linux/mdadm/4.nix index d929668a26a..abe8632773f 100644 --- a/pkgs/os-specific/linux/mdadm/4.nix +++ b/pkgs/os-specific/linux/mdadm/4.nix @@ -31,7 +31,7 @@ stdenv.mkDerivation rec { preConfigure = '' sed -e 's@/lib/udev@''${out}/lib/udev@' \ -e 's@ -Werror @ @' \ - -e 's@/usr/sbin/sendmail@/var/setuid-wrappers/sendmail@' -i Makefile + -e 's@/usr/sbin/sendmail@/var/permissions-wrappers/sendmail@' -i Makefile ''; meta = { diff --git a/pkgs/tools/security/ecryptfs/helper.nix b/pkgs/tools/security/ecryptfs/helper.nix index 0d4b37a8efc..6e3e6766a28 100644 --- a/pkgs/tools/security/ecryptfs/helper.nix +++ b/pkgs/tools/security/ecryptfs/helper.nix @@ -18,7 +18,7 @@ stdenv.mkDerivation rec { buildInputs = [ makeWrapper ]; - # Do not hardcode PATH to ${ecryptfs} as we need the script to invoke executables from /var/setuid-wrappers + # Do not hardcode PATH to ${ecryptfs} as we need the script to invoke executables from /var/permissions-wrappers installPhase = '' mkdir -p $out/bin $out/libexec cp $src $out/libexec/ecryptfs-helper.py diff --git a/pkgs/tools/system/cron/default.nix b/pkgs/tools/system/cron/default.nix index 3d03f19cb6f..f7f2a6158a2 100644 --- a/pkgs/tools/system/cron/default.nix +++ b/pkgs/tools/system/cron/default.nix @@ -23,7 +23,7 @@ stdenv.mkDerivation { #define _PATH_SENDMAIL "${sendmailPath}" #undef _PATH_DEFPATH - #define _PATH_DEFPATH "/var/setuid-wrappers:/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/run/current-system/sw/bin:/run/current-system/sw/sbin:/usr/bin:/bin" + #define _PATH_DEFPATH "/var/permissions-wrappers:/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/run/current-system/sw/bin:/run/current-system/sw/sbin:/usr/bin:/bin" __EOT__ # Implicit saved uids do not work here due to way NixOS uses setuid wrappers From a20e65724bad6472bbf40080955ecc5d0bb351e6 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 00:32:59 -0800 Subject: [PATCH 21/74] Fixing --- .../security/permissions-wrappers/default.nix | 72 +++++++++---------- .../permissions-wrapper.c | 2 +- .../setuid-wrapper-drv.nix | 21 +++--- 3 files changed, 46 insertions(+), 49 deletions(-) diff --git a/nixos/modules/security/permissions-wrappers/default.nix b/nixos/modules/security/permissions-wrappers/default.nix index 2f60d54fd77..2ec1e91cee9 100644 --- a/nixos/modules/security/permissions-wrappers/default.nix +++ b/nixos/modules/security/permissions-wrappers/default.nix @@ -66,6 +66,39 @@ let chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" ${permissionsWrapperDir}/${program} ''; + + mkActivationScript = programsToWrap: + lib.stringAfter [ "users" ] + '' + # Look in the system path and in the default profile for + # programs to be wrapped. + PERMISSIONS_WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin + + mkdir -p /run/permissions-wrapper-dirs + permissionsWrapperDir=$(mktemp --directory --tmpdir=/run/permissions-wrapper-dirs permissions-wrappers.XXXXXXXXXX) + chmod a+rx $permissionsWrapperDir + + ${programsToWrap} + + if [ -L ${permissionsWrapperDir} ]; then + # Atomically replace the symlink + # See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/ + old=$(readlink ${permissionsWrapperDir}) + ln --symbolic --force --no-dereference $permissionsWrapperDir ${permissionsWrapperDir}-tmp + mv --no-target-directory ${permissionsWrapperDir}-tmp ${permissionsWrapperDir} + rm --force --recursive $old + elif [ -d ${permissionsWrapperDir} ]; then + # Compatibility with old state, just remove the folder and symlink + rm -f ${permissionsWrapperDir}/* + # if it happens to be a tmpfs + ${pkgs.utillinux}/bin/umount ${permissionsWrapperDir} || true + rm -d ${permissionsWrapperDir} + ln -d --symbolic $permissionsWrapperDir ${permissionsWrapperDir} + else + # For initial setup + ln --symbolic $permissionsWrapperDir ${permissionsWrapperDir} + fi + ''; in { @@ -160,45 +193,10 @@ in ###### setcap activation script system.activationScripts.setcap = - lib.stringAfter [ "users" ] - '' - # Look in the system path and in the default profile for - # programs to be wrapped. - PERMISSIONS_WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin - - # When a program is removed from the security.permissionsWrappers.setcap - # list we have to remove all of the previous program wrappers - # and re-build them minus the wrapper for the program removed, - # hence the rm here in the activation script. - - rm -f ${permissionsWrapperDir}/* - - # Concatenate the generated shell slices to configure - # wrappers for each program needing specialized capabilities. - - ${lib.concatMapStrings configureSetcapWrapper (builtins.filter isNotNull cfg.setcap)} - ''; + mkActivationScript (lib.concatMapStrings configureSetcapWrapper (builtins.filter isNotNull cfg.setcap)); ###### setuid activation script system.activationScripts.setuid = - lib.stringAfter [ "users" ] - '' - # Look in the system path and in the default profile for - # programs to be wrapped. - PERMISSIONS_WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin - - # When a program is removed from the security.permissionsWrappers.setcap - # list we have to remove all of the previous program wrappers - # and re-build them minus the wrapper for the program removed, - # hence the rm here in the activation script. - - rm -f ${permissionsWrapperDir}/* - - # Concatenate the generated shell slices to configure - # wrappers for each program needing specialized capabilities. - - ${lib.concatMapStrings configureSetuidWrapper (builtins.filter isNotNull cfg.setuid)} - ''; - + mkActivationScript (lib.concatMapStrings configureSetuidWrapper (builtins.filter isNotNull cfg.setuid)); }; } diff --git a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c index effdaa93096..3cb5bb4f560 100644 --- a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c +++ b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c @@ -211,7 +211,7 @@ int main(int argc, char * * argv) // Read the capabilities set on the file and raise them in to the // Ambient set so the program we're wrapping receives the // capabilities too! - assert(!make_caps_ambient(selfPath)); + if (strcmp(wrapperType, "setcap") == 0) assert(!make_caps_ambient(selfPath)); execve(sourceProg, argv, environ); diff --git a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix b/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix index 273aaf2a88a..3bf3effb801 100644 --- a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix +++ b/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix @@ -5,18 +5,17 @@ let # Produce a shell-code splice intended to be stitched into one of # the build or install phases within the derivation. - mkSetuidWrapper = { program, source ? null, ...}: - '' - if ! source=${if source != null then source else "$(readlink -f $(PATH=$PERMISSIONS_WRAPPER_PATH type -tP ${program}))"}; then - # If we can't find the program, fall back to the - # system profile. - source=/nix/var/nix/profiles/default/bin/${program} - fi + mkSetuidWrapper = { program, source ? null, ...}: '' + if ! source=${if source != null then source else "$(readlink -f $(PATH=$PERMISSIONS_WRAPPER_PATH type -tP ${program}))"}; then + # If we can't find the program, fall back to the + # system profile. + source=/nix/var/nix/profiles/default/bin/${program} + fi - gcc -Wall -O2 -DWRAPPER_SETCAP=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.permissionsWrapperDir}\" \ - -lcap-ng -lcap ${./permissions-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 - ''; + gcc -Wall -O2 -DWRAPPER_SETUID=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.permissionsWrapperDir}\" \ + -lcap-ng -lcap ${./permissions-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 # This is only useful for Linux platforms and a kernel version of From e8bec4c75f9da5c2e6a12b8f96630dae2d2d57d6 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 00:35:01 -0800 Subject: [PATCH 22/74] Implicit declared function... --- .../security/permissions-wrappers/permissions-wrapper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c index 3cb5bb4f560..4a77e8aa3d5 100644 --- a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c +++ b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c @@ -211,7 +211,8 @@ int main(int argc, char * * argv) // Read the capabilities set on the file and raise them in to the // Ambient set so the program we're wrapping receives the // capabilities too! - if (strcmp(wrapperType, "setcap") == 0) assert(!make_caps_ambient(selfPath)); + if (strcmp(wrapperType, "setcap") == 0) + assert(!make_caps_ambient(selfPath)); execve(sourceProg, argv, environ); From 1ad541171e5d9362dce100de08d46fff91cab4d1 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 00:36:35 -0800 Subject: [PATCH 23/74] Hmm --- .../security/permissions-wrappers/permissions-wrapper.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c index 4a77e8aa3d5..9834bcd937b 100644 --- a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c +++ b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c @@ -211,8 +211,9 @@ int main(int argc, char * * argv) // Read the capabilities set on the file and raise them in to the // Ambient set so the program we're wrapping receives the // capabilities too! - if (strcmp(wrapperType, "setcap") == 0) - assert(!make_caps_ambient(selfPath)); + + + assert(!make_caps_ambient(selfPath)); execve(sourceProg, argv, environ); From 785684f6c2367ce979d908e25dd7831992f19f24 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 00:39:17 -0800 Subject: [PATCH 24/74] Ahhh, my compile-time macros confused me...of course they did... --- .../security/permissions-wrappers/permissions-wrapper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c index 9834bcd937b..f74a952b7d8 100644 --- a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c +++ b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c @@ -211,9 +211,9 @@ int main(int argc, char * * argv) // Read the capabilities set on the file and raise them in to the // Ambient set so the program we're wrapping receives the // capabilities too! - - + #ifdef WRAPPER_SETCAP assert(!make_caps_ambient(selfPath)); + #endif execve(sourceProg, argv, environ); From a4f905afc251e48ee106fdede8ad15e9cf5b4cdc Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 00:41:00 -0800 Subject: [PATCH 25/74] Enhhh I think compile time macros are gross --- .../permissions-wrappers/permissions-wrapper.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c index f74a952b7d8..2e7b1edde3b 100644 --- a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c +++ b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c @@ -8,6 +8,11 @@ #include #include #include +#include +#include +#include +#include +#include // Make sure assertions are not compiled out, we use them to codify // invariants about this program and we want it to fail fast and @@ -32,13 +37,6 @@ fprintf(stderr, "Program must be compiled with either the WRAPPER_SETCAP or WRAP exit(1); #endif -#ifdef WRAPPER_SETCAP -#include -#include -#include -#include -#include - // Update the capabilities of the running process to include the given // capability in the Ambient set. static void set_ambient_cap(cap_value_t cap) @@ -163,7 +161,6 @@ static int make_caps_ambient(const char *selfPath) return 0; } -#endif int main(int argc, char * * argv) { @@ -211,9 +208,8 @@ int main(int argc, char * * argv) // Read the capabilities set on the file and raise them in to the // Ambient set so the program we're wrapping receives the // capabilities too! - #ifdef WRAPPER_SETCAP - assert(!make_caps_ambient(selfPath)); - #endif + if (strcmp(wrapperType, "setcap") == 0) + assert(!make_caps_ambient(selfPath)); execve(sourceProg, argv, environ); From 21368c4c67580f6ff245636d4af37d3094a1cd09 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 00:58:44 -0800 Subject: [PATCH 26/74] Hmm, unnecessary --- nixos/modules/security/permissions-wrappers/default.nix | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/nixos/modules/security/permissions-wrappers/default.nix b/nixos/modules/security/permissions-wrappers/default.nix index 2ec1e91cee9..af8158aab92 100644 --- a/nixos/modules/security/permissions-wrappers/default.nix +++ b/nixos/modules/security/permissions-wrappers/default.nix @@ -22,7 +22,6 @@ let , source ? null , owner ? "nobody" , group ? "nogroup" - , setcap ? false }: '' cp ${setcapWrappers}/bin/${program}.wrapper ${permissionsWrapperDir}/${program} @@ -36,13 +35,7 @@ let # # Only set the capabilities though if we're being told to # do so. - ${ - if setcap then - '' - ${pkgs.libcap.out}/bin/setcap "cap_setpcap,${capabilities}" ${permissionsWrapperDir}/${program} - '' - else "" - } + ${pkgs.libcap.out}/bin/setcap "cap_setpcap,${capabilities}" ${permissionsWrapperDir}/${program} # Set the executable bit chmod u+rx,g+x,o+x ${permissionsWrapperDir}/${program} From 48a0c5a3a728418286d4790491ed1bd9c4df9e7e Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 01:00:46 -0800 Subject: [PATCH 27/74] More fixing --- nixos/modules/security/permissions-wrappers/default.nix | 1 - nixos/modules/tasks/network-interfaces.nix | 2 -- 2 files changed, 3 deletions(-) diff --git a/nixos/modules/security/permissions-wrappers/default.nix b/nixos/modules/security/permissions-wrappers/default.nix index af8158aab92..14f9dadcb24 100644 --- a/nixos/modules/security/permissions-wrappers/default.nix +++ b/nixos/modules/security/permissions-wrappers/default.nix @@ -106,7 +106,6 @@ in source = "${pkgs.iputils.out}/bin/ping"; owner = "nobody"; group = "nogroup"; - setcap = true; capabilities = "cap_net_raw+ep"; } ]; diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index a69435ff593..61519c6a3ce 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -902,13 +902,11 @@ in [ { program = "ping"; source = "${pkgs.iputils.out}/bin/ping"; - setcap = true; capabilities = "cap_net_raw+p"; } { program = "ping6"; source = "${pkgs.iputils.out}/bin/ping6"; - setcap = true; capabilities = "cap_net_raw+p"; } ] From 61fe8de40c9efbcd31301233e78278202485d8d8 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 01:03:18 -0800 Subject: [PATCH 28/74] Silly, should just have one activation script --- .../security/permissions-wrappers/default.nix | 69 +++++++++---------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/nixos/modules/security/permissions-wrappers/default.nix b/nixos/modules/security/permissions-wrappers/default.nix index 14f9dadcb24..55033266c9a 100644 --- a/nixos/modules/security/permissions-wrappers/default.nix +++ b/nixos/modules/security/permissions-wrappers/default.nix @@ -61,37 +61,7 @@ let ''; mkActivationScript = programsToWrap: - lib.stringAfter [ "users" ] - '' - # Look in the system path and in the default profile for - # programs to be wrapped. - PERMISSIONS_WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin - - mkdir -p /run/permissions-wrapper-dirs - permissionsWrapperDir=$(mktemp --directory --tmpdir=/run/permissions-wrapper-dirs permissions-wrappers.XXXXXXXXXX) - chmod a+rx $permissionsWrapperDir - - ${programsToWrap} - - if [ -L ${permissionsWrapperDir} ]; then - # Atomically replace the symlink - # See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/ - old=$(readlink ${permissionsWrapperDir}) - ln --symbolic --force --no-dereference $permissionsWrapperDir ${permissionsWrapperDir}-tmp - mv --no-target-directory ${permissionsWrapperDir}-tmp ${permissionsWrapperDir} - rm --force --recursive $old - elif [ -d ${permissionsWrapperDir} ]; then - # Compatibility with old state, just remove the folder and symlink - rm -f ${permissionsWrapperDir}/* - # if it happens to be a tmpfs - ${pkgs.utillinux}/bin/umount ${permissionsWrapperDir} || true - rm -d ${permissionsWrapperDir} - ln -d --symbolic $permissionsWrapperDir ${permissionsWrapperDir} - else - # For initial setup - ln --symbolic $permissionsWrapperDir ${permissionsWrapperDir} - fi - ''; +; in { @@ -184,11 +154,38 @@ in ''; ###### setcap activation script - system.activationScripts.setcap = - mkActivationScript (lib.concatMapStrings configureSetcapWrapper (builtins.filter isNotNull cfg.setcap)); + system.activationScripts.permissions-wrappers = + lib.stringAfter [ "users" ] + '' + # Look in the system path and in the default profile for + # programs to be wrapped. + PERMISSIONS_WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin - ###### setuid activation script - system.activationScripts.setuid = - mkActivationScript (lib.concatMapStrings configureSetuidWrapper (builtins.filter isNotNull cfg.setuid)); + mkdir -p /run/permissions-wrapper-dirs + permissionsWrapperDir=$(mktemp --directory --tmpdir=/run/permissions-wrapper-dirs permissions-wrappers.XXXXXXXXXX) + chmod a+rx $permissionsWrapperDir + + ${lib.concatMapStrings configureSetcapWrapper (builtins.filter isNotNull cfg.setcap)} + ${lib.concatMapStrings configureSetuidWrapper (builtins.filter isNotNull cfg.setuid)} + + if [ -L ${permissionsWrapperDir} ]; then + # Atomically replace the symlink + # See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/ + old=$(readlink ${permissionsWrapperDir}) + ln --symbolic --force --no-dereference $permissionsWrapperDir ${permissionsWrapperDir}-tmp + mv --no-target-directory ${permissionsWrapperDir}-tmp ${permissionsWrapperDir} + rm --force --recursive $old + elif [ -d ${permissionsWrapperDir} ]; then + # Compatibility with old state, just remove the folder and symlink + rm -f ${permissionsWrapperDir}/* + # if it happens to be a tmpfs + ${pkgs.utillinux}/bin/umount ${permissionsWrapperDir} || true + rm -d ${permissionsWrapperDir} + ln -d --symbolic $permissionsWrapperDir ${permissionsWrapperDir} + else + # For initial setup + ln --symbolic $permissionsWrapperDir ${permissionsWrapperDir} + fi + ''; }; } From fd974085bf5b7a18c0c053a1fdd331c523221fb1 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 01:04:12 -0800 Subject: [PATCH 29/74] It's clearly quite late --- nixos/modules/security/permissions-wrappers/default.nix | 3 --- 1 file changed, 3 deletions(-) diff --git a/nixos/modules/security/permissions-wrappers/default.nix b/nixos/modules/security/permissions-wrappers/default.nix index 55033266c9a..0ea465fbd78 100644 --- a/nixos/modules/security/permissions-wrappers/default.nix +++ b/nixos/modules/security/permissions-wrappers/default.nix @@ -59,9 +59,6 @@ let chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" ${permissionsWrapperDir}/${program} ''; - - mkActivationScript = programsToWrap: -; in { From f64b06a3e045c14110d9a7fcac9e4c8ee70ae8f0 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 01:13:19 -0800 Subject: [PATCH 30/74] Hmmm --- .../security/permissions-wrappers/default.nix | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/nixos/modules/security/permissions-wrappers/default.nix b/nixos/modules/security/permissions-wrappers/default.nix index 0ea465fbd78..bb5ffff8e27 100644 --- a/nixos/modules/security/permissions-wrappers/default.nix +++ b/nixos/modules/security/permissions-wrappers/default.nix @@ -23,11 +23,11 @@ let , owner ? "nobody" , group ? "nogroup" }: '' - cp ${setcapWrappers}/bin/${program}.wrapper ${permissionsWrapperDir}/${program} + cp ${setcapWrappers}/bin/${program}.wrapper $permissionsWrapperDir/${program} # Prevent races - chmod 0000 ${permissionsWrapperDir}/${program} - chown ${owner}.${group} ${permissionsWrapperDir}/${program} + chmod 0000 $permissionsWrapperDir/${program} + chown ${owner}.${group} $permissionsWrapperDir/${program} # Set desired capabilities on the file plus cap_setpcap so # the wrapper program can elevate the capabilities set on @@ -35,10 +35,10 @@ let # # Only set the capabilities though if we're being told to # do so. - ${pkgs.libcap.out}/bin/setcap "cap_setpcap,${capabilities}" ${permissionsWrapperDir}/${program} + ${pkgs.libcap.out}/bin/setcap "cap_setpcap,${capabilities}" $permissionsWrapperDir/${program} # Set the executable bit - chmod u+rx,g+x,o+x ${permissionsWrapperDir}/${program} + chmod u+rx,g+x,o+x $permissionsWrapperDir/${program} ''; ###### Activation script for the setuid wrappers @@ -51,13 +51,13 @@ let , setgid ? false , permissions ? "u+rx,g+x,o+x" }: '' - cp ${setuidWrappers}/bin/${program}.wrapper ${permissionsWrapperDir}/${program} + cp ${setuidWrappers}/bin/${program}.wrapper $permissionsWrapperDir/${program} # Prevent races - chmod 0000 ${permissionsWrapperDir}/${program} - chown ${owner}.${group} ${permissionsWrapperDir}/${program} + chmod 0000 $permissionsWrapperDir/${program} + chown ${owner}.${group} $permissionsWrapperDir/${program} - chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" ${permissionsWrapperDir}/${program} + chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" $permissionsWrapperDir/${program} ''; in { @@ -143,11 +143,11 @@ in # variable when initializing the shell environment.extraInit = '' # The permissions wrappers override other bin directories. - export PATH="${config.security.permissionsWrapperDir}:$PATH" + export PATH="${permissionsWrapperDir}:$PATH" ''; system.activationScripts.wrapper-dir = '' - mkdir -p "${config.security.permissionsWrapperDir}" + mkdir -p "${permissionsWrapperDir}" ''; ###### setcap activation script From ce36b58e21e8d15c1de0c300819b06e83a2a1c5a Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 01:31:49 -0800 Subject: [PATCH 31/74] Derp --- .../security/permissions-wrappers/default.nix | 16 +++++++++++++--- .../permissions-wrappers/setcap-wrapper-drv.nix | 2 +- .../permissions-wrappers/setuid-wrapper-drv.nix | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/nixos/modules/security/permissions-wrappers/default.nix b/nixos/modules/security/permissions-wrappers/default.nix index bb5ffff8e27..585e4a13be6 100644 --- a/nixos/modules/security/permissions-wrappers/default.nix +++ b/nixos/modules/security/permissions-wrappers/default.nix @@ -1,7 +1,7 @@ { config, lib, pkgs, ... }: let - inherit (config.security) permissionsWrapperDir; + inherit (config.security) run-permissionsWrapperDir permissionsWrapperDir; isNotNull = v: if v != null then true else false; @@ -132,6 +132,16 @@ in ''; }; + security.run-permissionsWrapperDir = lib.mkOption { + type = lib.types.path; + default = "/run/permissions-wrapper-dirs"; + internal = true; + description = '' + This option defines the run path to the permissions + wrappers. It should not be overriden. + ''; + }; + }; @@ -158,8 +168,8 @@ in # programs to be wrapped. PERMISSIONS_WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin - mkdir -p /run/permissions-wrapper-dirs - permissionsWrapperDir=$(mktemp --directory --tmpdir=/run/permissions-wrapper-dirs permissions-wrappers.XXXXXXXXXX) + mkdir -p ${run-permissionsWrapperDir} + permissionsWrapperDir=$(mktemp --directory --tmpdir=${run-permissionsWrapperDir} permissions-wrappers.XXXXXXXXXX) chmod a+rx $permissionsWrapperDir ${lib.concatMapStrings configureSetcapWrapper (builtins.filter isNotNull cfg.setcap)} diff --git a/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix b/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix index 04cae3c8493..3ec9b829a94 100644 --- a/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix +++ b/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix @@ -12,7 +12,7 @@ let source=/nix/var/nix/profiles/default/bin/${program} fi - gcc -Wall -O2 -DWRAPPER_SETCAP=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.permissionsWrapperDir}\" \ + gcc -Wall -O2 -DWRAPPER_SETCAP=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${cfg.run-permissionsWrapperDir}\" \ -lcap-ng -lcap ${./permissions-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 ''; diff --git a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix b/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix index 3bf3effb801..97dc3c1b0e0 100644 --- a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix +++ b/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix @@ -12,7 +12,7 @@ let source=/nix/var/nix/profiles/default/bin/${program} fi - gcc -Wall -O2 -DWRAPPER_SETUID=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.permissionsWrapperDir}\" \ + gcc -Wall -O2 -DWRAPPER_SETUID=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${cfg.run-permissionsWrapperDir}\" \ -lcap-ng -lcap ${./permissions-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 ''; From ad8fde5e5d9bc25a54ac238f485e28b37d6d185a Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 01:33:25 -0800 Subject: [PATCH 32/74] Andddd more derp --- .../security/permissions-wrappers/setcap-wrapper-drv.nix | 2 +- .../security/permissions-wrappers/setuid-wrapper-drv.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix b/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix index 3ec9b829a94..2ae3067b1b1 100644 --- a/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix +++ b/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix @@ -12,7 +12,7 @@ let source=/nix/var/nix/profiles/default/bin/${program} fi - gcc -Wall -O2 -DWRAPPER_SETCAP=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${cfg.run-permissionsWrapperDir}\" \ + gcc -Wall -O2 -DWRAPPER_SETCAP=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.run-permissionsWrapperDir}\" \ -lcap-ng -lcap ${./permissions-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 ''; diff --git a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix b/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix index 97dc3c1b0e0..42b00c8548a 100644 --- a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix +++ b/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix @@ -12,7 +12,7 @@ let source=/nix/var/nix/profiles/default/bin/${program} fi - gcc -Wall -O2 -DWRAPPER_SETUID=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${cfg.run-permissionsWrapperDir}\" \ + gcc -Wall -O2 -DWRAPPER_SETUID=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.run-permissionsWrapperDir}\" \ -lcap-ng -lcap ${./permissions-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 ''; From c30cf645f84232eba03d542519b5eca398a06825 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 02:06:24 -0800 Subject: [PATCH 33/74] Make setting of the wrapper macros a compile-time error --- .../security/permissions-wrappers/permissions-wrapper.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c index 2e7b1edde3b..6e00df9cef8 100644 --- a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c +++ b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c @@ -33,8 +33,7 @@ static char * wrapperType = "setcap"; #elif defined WRAPPER_SETUID static char * wrapperType = "setuid"; #else -fprintf(stderr, "Program must be compiled with either the WRAPPER_SETCAP or WRAPPER_SETUID macros specified!\n"); -exit(1); +#error Program must be compiled with either the WRAPPER_SETCAP or WRAPPER_SETUID macro #endif // Update the capabilities of the running process to include the given From 189a0c25796d10ee5ca9e7e61b6a79ff1656f177 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 02:07:36 -0800 Subject: [PATCH 34/74] Wrap with quotes as-per GCC's recommendation --- .../modules/security/permissions-wrappers/permissions-wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c index 6e00df9cef8..cb9d8d6b37b 100644 --- a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c +++ b/nixos/modules/security/permissions-wrappers/permissions-wrapper.c @@ -33,7 +33,7 @@ static char * wrapperType = "setcap"; #elif defined WRAPPER_SETUID static char * wrapperType = "setuid"; #else -#error Program must be compiled with either the WRAPPER_SETCAP or WRAPPER_SETUID macro +#error "Program must be compiled with either the WRAPPER_SETCAP or WRAPPER_SETUID macro" #endif // Update the capabilities of the running process to include the given From 01e6b82f3f5584f76ec46354d34a787968a7f262 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 09:20:15 -0800 Subject: [PATCH 35/74] Removing dead code --- .../permissions-wrappers/setcap-wrappers.nix | 162 ------------------ .../permissions-wrappers/setuid-wrappers.nix | 146 ---------------- 2 files changed, 308 deletions(-) delete mode 100644 nixos/modules/security/permissions-wrappers/setcap-wrappers.nix delete mode 100644 nixos/modules/security/permissions-wrappers/setuid-wrappers.nix diff --git a/nixos/modules/security/permissions-wrappers/setcap-wrappers.nix b/nixos/modules/security/permissions-wrappers/setcap-wrappers.nix deleted file mode 100644 index ead3cb219f1..00000000000 --- a/nixos/modules/security/permissions-wrappers/setcap-wrappers.nix +++ /dev/null @@ -1,162 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; with pkgs; - -let - - inherit (config.security) setcapWrapperDir; - - cfg = config.security.setcapCapabilities; - - # Produce a shell-code splice intended to be stitched into one of - # the build or install phases within the `setcapWrapper` derivation. - mkSetcapWrapper = { program, source ? null, ...}: - '' - if ! source=${if source != null then source else "$(readlink -f $(PATH=$SETCAP_PATH type -tP ${program}))"}; then - # If we can't find the program, fall back to the - # system profile. - source=/nix/var/nix/profiles/default/bin/${program} - fi - - gcc -Wall -O2 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${setcapWrapperDir}\" \ - -lcap-ng -lcap ${./setcap-wrapper.c} -o $out/bin/${program}.wrapper - ''; - - setcapWrappers = - - # This is only useful for Linux platforms and a kernel version of - # 4.3 or greater - assert pkgs.stdenv.isLinux; - assert versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.3"; - - pkgs.stdenv.mkDerivation { - name = "setcap-wrapper"; - unpackPhase = "true"; - buildInputs = [ linuxHeaders libcap libcap_ng ]; - installPhase = '' - mkdir -p $out/bin - - # Concat together all of our shell splices to compile - # binary wrapper programs for all configured setcap programs. - ${concatMapStrings mkSetcapWrapper cfg} - ''; - }; -in -{ - options = { - security.setcapCapabilities = mkOption { - type = types.listOf types.attrs; - default = []; - example = - [ { program = "ping"; - owner = "nobody"; - group = "nogroup"; - setcap = true; - capabilities = "cap_net_raw+ep"; - } - ]; - description = '' - This option sets capabilities on a wrapper program that - propagates those capabilities down to the wrapped, real - program. - - The `program` attribute is the name of the program to be - wrapped. If no `source` attribute is provided, specifying the - absolute path to the program, then the program will be - searched for in the path environment variable. - - NOTE: cap_setpcap, which is required for the wrapper program - to be able to raise caps into the Ambient set is NOT raised to - the Ambient set so that the real program cannot modify its own - capabilities!! This may be too restrictive for cases in which - the real program needs cap_setpcap but it at least leans on - the side security paranoid vs. too relaxed. - - The attribute `setcap` defaults to false and it will create a - wrapper program but never set the capability set on it. This - is done so that you can remove a capability sent entirely from - a wrapper program without also needing to go change any - absolute paths that may be directly referencing the wrapper - program. - ''; - }; - - security.setcapWrapperDir = mkOption { - type = types.path; - default = "/var/setcap-wrappers"; - internal = true; - description = '' - This option defines the path to the setcap wrappers. It - should generally not be overriden. - ''; - }; - - }; - - config = { - - # Make sure our setcap-wrapper dir exports to the PATH env - # variable when initializing the shell - environment.extraInit = '' - # The setcap wrappers override other bin directories. - export PATH="${config.security.setcapWrapperDir}:$PATH" - ''; - - system.activationScripts.setcap = - let - setcapPrograms = cfg; - configureSetcapWrapper = - { program - , capabilities - , source ? null - , owner ? "nobody" - , group ? "nogroup" - , setcap ? false - }: - '' - mkdir -p ${setcapWrapperDir} - - cp ${setcapWrappers}/bin/${program}.wrapper ${setcapWrapperDir}/${program} - - # Prevent races - chmod 0000 ${setcapWrapperDir}/${program} - chown ${owner}.${group} ${setcapWrapperDir}/${program} - - # Set desired capabilities on the file plus cap_setpcap so - # the wrapper program can elevate the capabilities set on - # its file into the Ambient set. - # - # Only set the capabilities though if we're being told to - # do so. - ${ - if setcap then - '' - ${libcap.out}/bin/setcap "cap_setpcap,${capabilities}" ${setcapWrapperDir}/${program} - '' - else "" - } - - # Set the executable bit - chmod u+rx,g+x,o+x ${setcapWrapperDir}/${program} - ''; - - in stringAfter [ "users" ] - '' - # Look in the system path and in the default profile for - # programs to be wrapped. - SETCAP_PATH=${config.system.path}/bin:${config.system.path}/sbin - - # When a program is removed from the security.setcapCapabilities - # list we have to remove all of the previous program wrappers - # and re-build them minus the wrapper for the program removed, - # hence the rm here in the activation script. - - rm -f ${setcapWrapperDir}/* - - # Concatenate the generated shell slices to configure - # wrappers for each program needing specialized capabilities. - - ${concatMapStrings configureSetcapWrapper setcapPrograms} - ''; - }; -} diff --git a/nixos/modules/security/permissions-wrappers/setuid-wrappers.nix b/nixos/modules/security/permissions-wrappers/setuid-wrappers.nix deleted file mode 100644 index fe220c94313..00000000000 --- a/nixos/modules/security/permissions-wrappers/setuid-wrappers.nix +++ /dev/null @@ -1,146 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - - inherit (config.security) wrapperDir; - - setuidWrapper = pkgs.stdenv.mkDerivation { - name = "setuid-wrapper"; - unpackPhase = "true"; - installPhase = '' - mkdir -p $out/bin - cp ${./setuid-wrapper.c} setuid-wrapper.c - gcc -Wall -O2 -DWRAPPER_DIR=\"/run/setuid-wrapper-dirs\" \ - setuid-wrapper.c -o $out/bin/setuid-wrapper - ''; - }; - -in - -{ - - ###### interface - - options = { - - security.setuidPrograms = mkOption { - type = types.listOf types.str; - default = []; - example = ["passwd"]; - description = '' - The Nix store cannot contain setuid/setgid programs directly. - For this reason, NixOS can automatically generate wrapper - programs that have the necessary privileges. This option - lists the names of programs in the system environment for - which setuid root wrappers should be created. - ''; - }; - - security.setuidOwners = mkOption { - type = types.listOf types.attrs; - default = []; - example = - [ { program = "sendmail"; - owner = "nobody"; - group = "postdrop"; - setuid = false; - setgid = true; - permissions = "u+rx,g+x,o+x"; - } - ]; - description = '' - This option allows the ownership and permissions on the setuid - wrappers for specific programs to be overridden from the - default (setuid root, but not setgid root). - ''; - }; - - security.wrapperDir = mkOption { - internal = true; - type = types.path; - default = "/var/setuid-wrappers"; - description = '' - This option defines the path to the setuid wrappers. It - should generally not be overriden. Some packages in Nixpkgs - expect that is - /var/setuid-wrappers. - ''; - }; - - }; - - - ###### implementation - - config = { - - security.setuidPrograms = [ "fusermount" ]; - - system.activationScripts.setuid = - let - setuidPrograms = - (map (x: { program = x; owner = "root"; group = "root"; setuid = true; }) - config.security.setuidPrograms) - ++ config.security.setuidOwners; - - makeSetuidWrapper = - { program - , source ? "" - , owner ? "nobody" - , group ? "nogroup" - , setuid ? false - , setgid ? false - , permissions ? "u+rx,g+x,o+x" - }: - - '' - if ! source=${if source != "" then source else "$(readlink -f $(PATH=$SETUID_PATH type -tP ${program}))"}; then - # If we can't find the program, fall back to the - # system profile. - source=/nix/var/nix/profiles/default/bin/${program} - fi - - cp ${setuidWrapper}/bin/setuid-wrapper $wrapperDir/${program} - echo -n "$source" > $wrapperDir/${program}.real - chmod 0000 $wrapperDir/${program} # to prevent races - chown ${owner}.${group} $wrapperDir/${program} - chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" $wrapperDir/${program} - ''; - - in stringAfter [ "users" ] - '' - # Look in the system path and in the default profile for - # programs to be wrapped. - SETUID_PATH=${config.system.path}/bin:${config.system.path}/sbin - - mkdir -p /run/setuid-wrapper-dirs - wrapperDir=$(mktemp --directory --tmpdir=/run/setuid-wrapper-dirs setuid-wrappers.XXXXXXXXXX) - chmod a+rx $wrapperDir - - ${concatMapStrings makeSetuidWrapper setuidPrograms} - - if [ -L ${wrapperDir} ]; then - # Atomically replace the symlink - # See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/ - old=$(readlink ${wrapperDir}) - ln --symbolic --force --no-dereference $wrapperDir ${wrapperDir}-tmp - mv --no-target-directory ${wrapperDir}-tmp ${wrapperDir} - rm --force --recursive $old - elif [ -d ${wrapperDir} ]; then - # Compatibility with old state, just remove the folder and symlink - rm -f ${wrapperDir}/* - # if it happens to be a tmpfs - ${pkgs.utillinux}/bin/umount ${wrapperDir} || true - rm -d ${wrapperDir} - ln -d --symbolic $wrapperDir ${wrapperDir} - else - # For initial setup - ln --symbolic $wrapperDir ${wrapperDir} - fi - ''; - - }; - -} From 9de070e620544f9637b20966eec62cbff42988d8 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Thu, 26 Jan 2017 09:39:37 -0800 Subject: [PATCH 36/74] Setuid wrapper should not be constrained to a specific linux kernel version --- nixos/modules/security/permissions-wrappers/default.nix | 7 ------- .../security/permissions-wrappers/setuid-wrapper-drv.nix | 1 - 2 files changed, 8 deletions(-) diff --git a/nixos/modules/security/permissions-wrappers/default.nix b/nixos/modules/security/permissions-wrappers/default.nix index 585e4a13be6..480bd371040 100644 --- a/nixos/modules/security/permissions-wrappers/default.nix +++ b/nixos/modules/security/permissions-wrappers/default.nix @@ -92,13 +92,6 @@ in capabilities!! This may be too restrictive for cases in which the real program needs cap_setpcap but it at least leans on the side security paranoid vs. too relaxed. - - The attribute `setcap` defaults to false and it will create a - wrapper program but never set the capability set on it. This - is done so that you can remove a capability sent entirely from - a wrapper program without also needing to go change any - absolute paths that may be directly referencing the wrapper - program. ''; }; diff --git a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix b/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix index 42b00c8548a..53cce2ff48e 100644 --- a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix +++ b/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix @@ -21,7 +21,6 @@ in # This is only useful for Linux platforms and a kernel version of # 4.3 or greater assert pkgs.stdenv.isLinux; -assert lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3"; pkgs.stdenv.mkDerivation { name = "setuid-wrapper"; From e92b8402b05f34072a20075ed54660e7a7237cc3 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sat, 28 Jan 2017 20:48:03 -0800 Subject: [PATCH 37/74] Addressing PR feedback --- nixos/doc/manual/release-notes/rl-1609.xml | 2 +- nixos/doc/manual/release-notes/rl-1703.xml | 8 + nixos/modules/config/shells-environment.nix | 4 +- .../installer/tools/nixos-generate-config.pl | 2 +- .../modules/installer/tools/nixos-install.sh | 7 +- nixos/modules/module-list.nix | 2 +- nixos/modules/programs/kbdlight.nix | 9 +- nixos/modules/programs/light.nix | 9 +- nixos/modules/programs/shadow.nix | 48 +---- nixos/modules/security/apparmor-suid.nix | 4 +- .../security/chromium-suid-sandbox.nix | 6 +- nixos/modules/security/duosec.nix | 11 +- nixos/modules/security/pam.nix | 33 +-- nixos/modules/security/pam_usb.nix | 17 +- .../security/permissions-wrappers/default.nix | 191 ------------------ nixos/modules/security/polkit.nix | 18 +- nixos/modules/security/sudo.nix | 17 +- nixos/modules/security/wrappers/default.nix | 191 ++++++++++++++++++ .../permissions-wrapper.c | 0 .../setcap-wrapper-drv.nix | 4 +- .../setuid-wrapper-drv.nix | 12 +- nixos/modules/services/logging/logcheck.nix | 4 +- nixos/modules/services/mail/dovecot.nix | 2 +- nixos/modules/services/mail/exim.nix | 12 +- nixos/modules/services/mail/mail.nix | 2 +- nixos/modules/services/monitoring/munin.nix | 4 +- nixos/modules/services/monitoring/smartd.nix | 2 +- .../services/network-filesystems/samba.nix | 2 +- nixos/modules/services/networking/gale.nix | 2 +- nixos/modules/services/networking/prayer.nix | 2 +- .../modules/services/networking/smokeping.nix | 20 +- nixos/modules/services/scheduling/atd.nix | 2 +- nixos/modules/services/scheduling/cron.nix | 18 +- nixos/modules/services/scheduling/fcron.nix | 13 +- nixos/modules/services/system/dbus.nix | 4 +- .../x11/desktop-managers/enlightenment.nix | 11 +- .../services/x11/desktop-managers/kde4.nix | 2 +- .../services/x11/desktop-managers/kde5.nix | 2 +- nixos/modules/system/boot/stage-2-init.sh | 8 +- nixos/modules/tasks/network-interfaces.nix | 45 ++--- .../virtualisation/virtualbox-host.nix | 4 +- nixos/tests/smokeping.nix | 2 +- .../applications/editors/sublime3/default.nix | 2 +- .../networking/browsers/chromium/default.nix | 4 +- .../gale/gale-install.in.patch | 2 +- .../gitlab/remove-hardcoded-locations.patch | 2 +- .../virtualization/virtualbox/hardened.patch | 6 +- pkgs/build-support/build-fhs-userenv/env.nix | 2 +- pkgs/desktops/enlightenment/enlightenment.nix | 6 +- .../kinit/start_kdeinit-path.patch | 2 +- .../development/libraries/libgksu/default.nix | 4 +- pkgs/development/libraries/polkit/default.nix | 2 +- pkgs/development/tools/unity3d/default.nix | 2 +- pkgs/os-specific/linux/fuse/default.nix | 2 +- pkgs/os-specific/linux/mdadm/4.nix | 2 +- pkgs/os-specific/linux/mdadm/default.nix | 2 +- pkgs/os-specific/linux/pam/default.nix | 2 +- pkgs/os-specific/linux/util-linux/default.nix | 2 +- pkgs/servers/interlock/default.nix | 2 +- pkgs/servers/mail/petidomo/default.nix | 2 +- .../nagios/plugins/official-2.x.nix | 4 +- pkgs/tools/X11/x11vnc/default.nix | 4 +- pkgs/tools/admin/certbot/default.nix | 2 +- pkgs/tools/misc/debian-devscripts/default.nix | 2 +- pkgs/tools/security/ecryptfs/default.nix | 2 +- pkgs/tools/security/ecryptfs/helper.nix | 2 +- pkgs/tools/security/sudo/default.nix | 2 +- pkgs/tools/system/at/default.nix | 2 +- pkgs/tools/system/cron/default.nix | 2 +- pkgs/tools/system/ts/default.nix | 2 +- 70 files changed, 320 insertions(+), 510 deletions(-) delete mode 100644 nixos/modules/security/permissions-wrappers/default.nix create mode 100644 nixos/modules/security/wrappers/default.nix rename nixos/modules/security/{permissions-wrappers => wrappers}/permissions-wrapper.c (100%) rename nixos/modules/security/{permissions-wrappers => wrappers}/setcap-wrapper-drv.nix (92%) rename nixos/modules/security/{permissions-wrappers => wrappers}/setuid-wrapper-drv.nix (75%) diff --git a/nixos/doc/manual/release-notes/rl-1609.xml b/nixos/doc/manual/release-notes/rl-1609.xml index bf8be1b68f2..ade7d5581ce 100644 --- a/nixos/doc/manual/release-notes/rl-1609.xml +++ b/nixos/doc/manual/release-notes/rl-1609.xml @@ -202,7 +202,7 @@ following incompatible changes: The directory container setuid wrapper programs, - /var/permissions-wrappers, /var/setuid-wrappers, is now updated atomically to prevent failures if the switch to a new configuration is interrupted. diff --git a/nixos/doc/manual/release-notes/rl-1703.xml b/nixos/doc/manual/release-notes/rl-1703.xml index 177010e2a32..94aa674fed6 100644 --- a/nixos/doc/manual/release-notes/rl-1703.xml +++ b/nixos/doc/manual/release-notes/rl-1703.xml @@ -15,6 +15,14 @@ has the following highlights: xlink:href="https://nixos.org/nixpkgs/manual/#sec-overlays-install">Nixpkgs manual for more information. + + + + Setting capabilities on programs is now supported with a + setcap-wrapper functionality. This + functionality and the setuid-wrapper are merged + into a single "wrappers" module. + The following new services were added since the last release: diff --git a/nixos/modules/config/shells-environment.nix b/nixos/modules/config/shells-environment.nix index 7003c074522..8a7b3ea0bfd 100644 --- a/nixos/modules/config/shells-environment.nix +++ b/nixos/modules/config/shells-environment.nix @@ -168,8 +168,8 @@ in ${cfg.extraInit} - # The setuid wrappers override other bin directories. - export PATH="${config.security.permissionsWrapperDir}:$PATH" + # The setuid/setcap wrappers override other bin directories. + export PATH="${config.security.wrapperDir}:$PATH" # ~/bin if it exists overrides other bin directories. export PATH="$HOME/bin:$PATH" diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl index bb379dafc64..657c28f095d 100644 --- a/nixos/modules/installer/tools/nixos-generate-config.pl +++ b/nixos/modules/installer/tools/nixos-generate-config.pl @@ -343,7 +343,7 @@ foreach my $fs (read_file("/proc/self/mountinfo")) { # Skip special filesystems. next if in($mountPoint, "/proc") || in($mountPoint, "/dev") || in($mountPoint, "/sys") || in($mountPoint, "/run") || $mountPoint eq "/var/lib/nfs/rpc_pipefs"; - next if $mountPoint eq "/var/permissions-wrappers"; + next if $mountPoint eq "/run/wrappers"; # Skip the optional fields. my $n = 6; $n++ while $fields[$n] ne "-"; $n++; diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh index 4e9f8ab60f2..36b1a47956d 100644 --- a/nixos/modules/installer/tools/nixos-install.sh +++ b/nixos/modules/installer/tools/nixos-install.sh @@ -92,14 +92,13 @@ fi mkdir -m 0755 -p $mountPoint/dev $mountPoint/proc $mountPoint/sys $mountPoint/etc $mountPoint/run $mountPoint/home mkdir -m 01777 -p $mountPoint/tmp mkdir -m 0755 -p $mountPoint/tmp/root -mkdir -m 0755 -p $mountPoint/var/permissions-wrappers +mkdir -m 0755 -p $mountPoint/var mkdir -m 0700 -p $mountPoint/root mount --rbind /dev $mountPoint/dev mount --rbind /proc $mountPoint/proc mount --rbind /sys $mountPoint/sys mount --rbind / $mountPoint/tmp/root mount -t tmpfs -o "mode=0755" none $mountPoint/run -mount -t tmpfs -o "mode=0755" none $mountPoint/var/permissions-wrappers rm -rf $mountPoint/var/run ln -s /run $mountPoint/var/run for f in /etc/resolv.conf /etc/hosts; do rm -f $mountPoint/$f; [ -f "$f" ] && cp -Lf $f $mountPoint/etc/; done @@ -260,9 +259,9 @@ chroot $mountPoint /nix/var/nix/profiles/system/activate # Ask the user to set a root password. -if [ -z "$noRootPasswd" ] && chroot $mountPoint [ -x /var/permissions-wrappers/passwd ] && [ -t 0 ]; then +if [ -z "$noRootPasswd" ] && chroot $mountPoint [ -x /run/wrappers/passwd ] && [ -t 0 ]; then echo "setting root password..." - chroot $mountPoint /var/permissions-wrappers/passwd + chroot $mountPoint /run/wrappers/passwd fi diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index f7206ea931b..bd351460a52 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -113,7 +113,7 @@ ./security/prey.nix ./security/rngd.nix ./security/rtkit.nix - ./security/permissions-wrappers + ./security/wrappers ./security/sudo.nix ./services/amqp/activemq/default.nix ./services/amqp/rabbitmq.nix diff --git a/nixos/modules/programs/kbdlight.nix b/nixos/modules/programs/kbdlight.nix index 30767a03291..0172368e968 100644 --- a/nixos/modules/programs/kbdlight.nix +++ b/nixos/modules/programs/kbdlight.nix @@ -11,13 +11,6 @@ in config = mkIf cfg.enable { environment.systemPackages = [ pkgs.kbdlight ]; - - security.permissionsWrappers.setuid = - [ { program = "kbdlight"; - source = "${pkgs.kbdlight.out}/bin/kbdlight"; - owner = "root"; - group = "root"; - setuid = true; - }]; + security.setuidPrograms = [ "kbdlight" ]; }; } diff --git a/nixos/modules/programs/light.nix b/nixos/modules/programs/light.nix index c89f8e93721..09cd1113d9c 100644 --- a/nixos/modules/programs/light.nix +++ b/nixos/modules/programs/light.nix @@ -21,13 +21,6 @@ in config = mkIf cfg.enable { environment.systemPackages = [ pkgs.light ]; - - security.permissionsWrappers.setuid = - [ { program = "light"; - source = "${pkgs.light.out}/bin/light"; - owner = "root"; - group = "root"; - setuid = true; - }]; + security.setuidPrograms = [ "light" ]; }; } diff --git a/nixos/modules/programs/shadow.nix b/nixos/modules/programs/shadow.nix index 08d96cbcf4b..c5a50318026 100644 --- a/nixos/modules/programs/shadow.nix +++ b/nixos/modules/programs/shadow.nix @@ -101,49 +101,9 @@ in chpasswd = { rootOK = true; }; }; - - security.permissionsWrappers.setuid = - [ - { program = "su"; - source = "${pkgs.shadow.su}/bin/su"; - owner = "root"; - group = "root"; - setuid = true; - } - - { program = "chfn"; - source = "${pkgs.shadow.out}/bin/chfn"; - owner = "root"; - group = "root"; - setuid = true; - } - ] ++ - (lib.optionals config.users.mutableUsers - map (x: x // { owner = "root"; - group = "root"; - setuid = true; - }) - [ - { program = "passwd"; - source = "${pkgs.shadow.out}/bin/passwd"; - } - - { program = "sg"; - source = "${pkgs.shadow.out}/bin/sg"; - } - - { program = "newgrp"; - source = "${pkgs.shadow.out}/bin/newgrp"; - } - - { program = "newuidmap"; - source = "${pkgs.shadow.out}/bin/newuidmap"; - } - - { program = "newgidmap"; - source = "${pkgs.shadow.out}/bin/newgidmap"; - } - ] - ); + security.setuidPrograms = [ + "su" "chfn" "newuidmap" "newgidmap" + ] ++ lib.optionals config.users.mutableUsers + [ "passwd" "sg" "newgrp" ]; }; } diff --git a/nixos/modules/security/apparmor-suid.nix b/nixos/modules/security/apparmor-suid.nix index 799f27b6708..e7b870864ee 100644 --- a/nixos/modules/security/apparmor-suid.nix +++ b/nixos/modules/security/apparmor-suid.nix @@ -19,7 +19,7 @@ with lib; config = mkIf (cfg.confineSUIDApplications) { security.apparmor.profiles = [ (pkgs.writeText "ping" '' #include - /var/permissions-wrappers/ping { + /run/wrappers/ping { #include #include #include @@ -33,7 +33,7 @@ with lib; ${pkgs.attr.out}/lib/libattr.so* mr, ${pkgs.iputils}/bin/ping mixr, - /var/permissions-wrappers/ping.real r, + /run/wrappers/ping.real r, #/etc/modules.conf r, diff --git a/nixos/modules/security/chromium-suid-sandbox.nix b/nixos/modules/security/chromium-suid-sandbox.nix index 6fe25213639..0699fbb728a 100644 --- a/nixos/modules/security/chromium-suid-sandbox.nix +++ b/nixos/modules/security/chromium-suid-sandbox.nix @@ -27,10 +27,6 @@ in config = mkIf cfg.enable { environment.systemPackages = [ sandbox ]; - security.permissionsWrappers.setuid = [ - { program = sandbox.passthru.sandboxExecutableName; - source = "${sandbox}/bin/${sandbox.passthru.sandboxExecutableName}"; - } - ]; + security.setuidPrograms = [ sandbox.passthru.sandboxExecutableName ]; }; } diff --git a/nixos/modules/security/duosec.nix b/nixos/modules/security/duosec.nix index e5b35427015..ee62c34438e 100644 --- a/nixos/modules/security/duosec.nix +++ b/nixos/modules/security/duosec.nix @@ -188,16 +188,7 @@ in environment.systemPackages = [ pkgs.duo-unix ]; - security.permissionsWrappers.setuid = - [ - { program = "login_duo"; - source = "${pkgs.duo-unix.out}/bin/login_duo"; - owner = "root"; - group = "root"; - setuid = true; - } - ]; - + security.setuidPrograms = [ "login_duo" ]; environment.etc = loginCfgFile ++ pamCfgFile; /* If PAM *and* SSH are enabled, then don't do anything special. diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index c5088b64bb3..3c944acf6cf 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -472,33 +472,14 @@ in ++ optionals config.security.pam.enableU2F [ pkgs.pam_u2f ] ++ optionals config.security.pam.enableEcryptfs [ pkgs.ecryptfs ]; - security.permissionsWrappers.setuid = - [ - { program = "unix_chkpwd"; - source = "${pkgs.pam}/sbin/unix_chkpwd.orig"; - owner = "root"; - group = "root"; - setuid = true; - } + security.setuidPrograms = + optionals config.security.pam.enableEcryptfs [ "mount.ecryptfs_private" "umount.ecryptfs_private" ]; - - - ] ++ (optional config.security.pam.enableEcryptfs - { program = "umount.ecryptfs_private"; - source = "${pkgs.ecryptfs.out}/bin/umount.ecryptfs_private"; - owner = "root"; - group = "root"; - setuid = true; - } - ) ++ (optional config.security.pam.enableEcryptfs - { program = "mount.ecryptfs_private"; - source = "${pkgs.ecryptfs.out}/bin/mount.ecryptfs_private"; - owner = "root"; - group = "root"; - setuid = true; - } - ); - + security.wrappers.unix_chkpwd = { + source = "${pkgs.pam}/sbin/unix_chkpwd.orig"; + owner = "root"; + setuid = true; + }; environment.etc = mapAttrsToList (n: v: makePAMService v) config.security.pam.services; diff --git a/nixos/modules/security/pam_usb.nix b/nixos/modules/security/pam_usb.nix index 53a7921a244..032f8e38d11 100644 --- a/nixos/modules/security/pam_usb.nix +++ b/nixos/modules/security/pam_usb.nix @@ -33,22 +33,7 @@ in config = mkIf (cfg.enable || anyUsbAuth) { # Make sure pmount and pumount are setuid wrapped. - security.permissionsWrappers.setuid = - [ - { program = "pmount"; - source = "${pkgs.pmount.out}/bin/pmount"; - owner = "root"; - group = "root"; - setuid = true; - } - - { program = "pumount"; - source = "${pkgs.pmount.out}/bin/pumount"; - owner = "root"; - group = "root"; - setuid = true; - } - ]; + security.setuidPrograms = [ "pmount" "pumount" ]; environment.systemPackages = [ pkgs.pmount ]; diff --git a/nixos/modules/security/permissions-wrappers/default.nix b/nixos/modules/security/permissions-wrappers/default.nix deleted file mode 100644 index 480bd371040..00000000000 --- a/nixos/modules/security/permissions-wrappers/default.nix +++ /dev/null @@ -1,191 +0,0 @@ -{ config, lib, pkgs, ... }: -let - - inherit (config.security) run-permissionsWrapperDir permissionsWrapperDir; - - isNotNull = v: if v != null then true else false; - - cfg = config.security.permissionsWrappers; - - setcapWrappers = import ./setcap-wrapper-drv.nix { - inherit config lib pkgs; - }; - - setuidWrappers = import ./setuid-wrapper-drv.nix { - inherit config lib pkgs; - }; - - ###### Activation script for the setcap wrappers - configureSetcapWrapper = - { program - , capabilities - , source ? null - , owner ? "nobody" - , group ? "nogroup" - }: '' - cp ${setcapWrappers}/bin/${program}.wrapper $permissionsWrapperDir/${program} - - # Prevent races - chmod 0000 $permissionsWrapperDir/${program} - chown ${owner}.${group} $permissionsWrapperDir/${program} - - # Set desired capabilities on the file plus cap_setpcap so - # the wrapper program can elevate the capabilities set on - # its file into the Ambient set. - # - # Only set the capabilities though if we're being told to - # do so. - ${pkgs.libcap.out}/bin/setcap "cap_setpcap,${capabilities}" $permissionsWrapperDir/${program} - - # Set the executable bit - chmod u+rx,g+x,o+x $permissionsWrapperDir/${program} - ''; - - ###### Activation script for the setuid wrappers - configureSetuidWrapper = - { program - , source ? null - , owner ? "nobody" - , group ? "nogroup" - , setuid ? false - , setgid ? false - , permissions ? "u+rx,g+x,o+x" - }: '' - cp ${setuidWrappers}/bin/${program}.wrapper $permissionsWrapperDir/${program} - - # Prevent races - chmod 0000 $permissionsWrapperDir/${program} - chown ${owner}.${group} $permissionsWrapperDir/${program} - - chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" $permissionsWrapperDir/${program} - ''; -in -{ - - ###### interface - - options = { - security.permissionsWrappers.setcap = lib.mkOption { - type = lib.types.listOf lib.types.attrs; - default = []; - example = - [ { program = "ping"; - source = "${pkgs.iputils.out}/bin/ping"; - owner = "nobody"; - group = "nogroup"; - capabilities = "cap_net_raw+ep"; - } - ]; - description = '' - This option sets capabilities on a wrapper program that - propagates those capabilities down to the wrapped, real - program. - - The `program` attribute is the name of the program to be - wrapped. If no `source` attribute is provided, specifying the - absolute path to the program, then the program will be - searched for in the path environment variable. - - NOTE: cap_setpcap, which is required for the wrapper program - to be able to raise caps into the Ambient set is NOT raised to - the Ambient set so that the real program cannot modify its own - capabilities!! This may be too restrictive for cases in which - the real program needs cap_setpcap but it at least leans on - the side security paranoid vs. too relaxed. - ''; - }; - - security.permissionsWrappers.setuid = lib.mkOption { - type = lib.types.listOf lib.types.attrs; - default = []; - example = - [ { program = "sendmail"; - source = "/nix/store/.../bin/sendmail"; - owner = "nobody"; - group = "postdrop"; - setuid = false; - setgid = true; - permissions = "u+rx,g+x,o+x"; - } - ]; - description = '' - This option allows the ownership and permissions on the setuid - wrappers for specific programs to be overridden from the - default (setuid root, but not setgid root). - ''; - }; - - security.permissionsWrapperDir = lib.mkOption { - type = lib.types.path; - default = "/var/permissions-wrappers"; - internal = true; - description = '' - This option defines the path to the permissions wrappers. It - should not be overriden. - ''; - }; - - security.run-permissionsWrapperDir = lib.mkOption { - type = lib.types.path; - default = "/run/permissions-wrapper-dirs"; - internal = true; - description = '' - This option defines the run path to the permissions - wrappers. It should not be overriden. - ''; - }; - - }; - - - ###### implementation - - config = { - - # Make sure our setcap-wrapper dir exports to the PATH env - # variable when initializing the shell - environment.extraInit = '' - # The permissions wrappers override other bin directories. - export PATH="${permissionsWrapperDir}:$PATH" - ''; - - system.activationScripts.wrapper-dir = '' - mkdir -p "${permissionsWrapperDir}" - ''; - - ###### setcap activation script - system.activationScripts.permissions-wrappers = - lib.stringAfter [ "users" ] - '' - # Look in the system path and in the default profile for - # programs to be wrapped. - PERMISSIONS_WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin - - mkdir -p ${run-permissionsWrapperDir} - permissionsWrapperDir=$(mktemp --directory --tmpdir=${run-permissionsWrapperDir} permissions-wrappers.XXXXXXXXXX) - chmod a+rx $permissionsWrapperDir - - ${lib.concatMapStrings configureSetcapWrapper (builtins.filter isNotNull cfg.setcap)} - ${lib.concatMapStrings configureSetuidWrapper (builtins.filter isNotNull cfg.setuid)} - - if [ -L ${permissionsWrapperDir} ]; then - # Atomically replace the symlink - # See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/ - old=$(readlink ${permissionsWrapperDir}) - ln --symbolic --force --no-dereference $permissionsWrapperDir ${permissionsWrapperDir}-tmp - mv --no-target-directory ${permissionsWrapperDir}-tmp ${permissionsWrapperDir} - rm --force --recursive $old - elif [ -d ${permissionsWrapperDir} ]; then - # Compatibility with old state, just remove the folder and symlink - rm -f ${permissionsWrapperDir}/* - # if it happens to be a tmpfs - ${pkgs.utillinux}/bin/umount ${permissionsWrapperDir} || true - rm -d ${permissionsWrapperDir} - ln -d --symbolic $permissionsWrapperDir ${permissionsWrapperDir} - else - # For initial setup - ln --symbolic $permissionsWrapperDir ${permissionsWrapperDir} - fi - ''; - }; -} diff --git a/nixos/modules/security/polkit.nix b/nixos/modules/security/polkit.nix index 098319d5ded..547b40cedfd 100644 --- a/nixos/modules/security/polkit.nix +++ b/nixos/modules/security/polkit.nix @@ -83,22 +83,8 @@ in security.pam.services.polkit-1 = {}; - security.permissionsWrappers.setuid = - [ - { program = "pkexec"; - source = "${pkgs.polkit.out}/bin/pkexec"; - owner = "root"; - group = "root"; - setuid = true; - } - - { program = "polkit-agent-helper-1"; - owner = "root"; - group = "root"; - setuid = true; - source = "${pkgs.polkit.out}/lib/polkit-1/polkit-agent-helper-1"; - } - ]; + security.setuidPrograms = [ "pkexec" ]; + security.wrappers."polkit-agent-helper-1".source = "${pkgs.polkit.out}/lib/polkit-1/polkit-agent-helper-1"; system.activationScripts.polkit = '' diff --git a/nixos/modules/security/sudo.nix b/nixos/modules/security/sudo.nix index 652f23c2938..f5612e1b0c5 100644 --- a/nixos/modules/security/sudo.nix +++ b/nixos/modules/security/sudo.nix @@ -81,22 +81,7 @@ in ${cfg.extraConfig} ''; - security.permissionsWrappers.setuid = - [ - { program = "sudo"; - source = "${pkgs.sudo.out}/bin/sudo"; - owner = "root"; - group = "root"; - setuid = true; - } - - { program = "sudoedit"; - source = "${pkgs.sudo.out}/bin/sudoedit"; - owner = "root"; - group = "root"; - setuid = true; - } - ]; + security.setuidPrograms = [ "sudo" "sudoedit" ]; environment.systemPackages = [ sudo ]; diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix new file mode 100644 index 00000000000..d12209b375b --- /dev/null +++ b/nixos/modules/security/wrappers/default.nix @@ -0,0 +1,191 @@ +{ config, lib, pkgs, ... }: +let + + inherit (config.security) wrapperDir; + + isNotNull = v: if v != null || v != "" then true else false; + + cfg = config.security.wrappers; + + setcapWrappers = import ./setcap-wrapper-drv.nix { + inherit config lib pkgs; + }; + + setuidWrappers = import ./setuid-wrapper-drv.nix { + inherit config lib pkgs; + }; + + ###### Activation script for the setcap wrappers + mkSetcapProgram = + { program + , capabilities + , source ? null + , owner ? "nobody" + , group ? "nogroup" + ... + }: '' + cp ${setcapWrappers}/bin/${program}.wrapper $wrapperDir/${program} + + # Prevent races + chmod 0000 $wrapperDir/${program} + chown ${owner}.${group} $wrapperDir/${program} + + # Set desired capabilities on the file plus cap_setpcap so + # the wrapper program can elevate the capabilities set on + # its file into the Ambient set. + # + # Only set the capabilities though if we're being told to + # do so. + ${pkgs.libcap.out}/bin/setcap "cap_setpcap,${capabilities}" $wrapperDir/${program} + + # Set the executable bit + chmod u+rx,g+x,o+x $wrapperDir/${program} + ''; + + ###### Activation script for the setuid wrappers + mkSetuidProgram = + { program + , source ? null + , owner ? "nobody" + , group ? "nogroup" + , setuid ? false + , setgid ? false + , permissions ? "u+rx,g+x,o+x" + ... + }: '' + cp ${setuidWrappers}/bin/${program}.wrapper $wrapperDir/${program} + + # Prevent races + chmod 0000 $wrapperDir/${program} + chown ${owner}.${group} $wrapperDir/${program} + + chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" $wrapperDir/${program} + ''; +in +{ + + ###### interface + + options = { + security.wrappers.setcap = lib.mkOption { + type = lib.types.listOf lib.types.attrs; + default = []; + example = + [ { program = "ping"; + source = "${pkgs.iputils.out}/bin/ping"; + owner = "nobody"; + group = "nogroup"; + capabilities = "cap_net_raw+ep"; + } + ]; + description = '' + This option sets capabilities on a wrapper program that + propagates those capabilities down to the wrapped, real + program. + + The program attribute is the name of the + program to be wrapped. If no source + attribute is provided, specifying the absolute path to the + program, then the program will be searched for in the path + environment variable. + + NOTE: cap_setpcap, which is required for the wrapper program + to be able to raise caps into the Ambient set is NOT raised to + the Ambient set so that the real program cannot modify its own + capabilities!! This may be too restrictive for cases in which + the real program needs cap_setpcap but it at least leans on + the side security paranoid vs. too relaxed. + ''; + }; + + security.setuidPrograms = mkOption { + type = types.listOf types.str; + default = []; + example = ["passwd"]; + description = '' + The Nix store cannot contain setuid/setgid programs directly. + For this reason, NixOS can automatically generate wrapper + programs that have the necessary privileges. This option + lists the names of programs in the system environment for + which setuid root wrappers should be created. + ''; + }; + + security.wrappers = lib.mkOption { + type = lib.types.attrs; + default = {}; + example = { + sendmail.source = "/nix/store/.../bin/sendmail"; + }; + description = '' + This option allows the ownership and permissions on the setuid + wrappers for specific programs to be overridden from the + default (setuid root, but not setgid root). + ''; + }; + + security.old-wrapperDir = lib.mkOption { + type = lib.types.path; + default = "/var/setuid-wrappers"; + internal = true; + description = '' + This option defines the path to the wrapper programs. It + should not be overriden. + ''; + }; + + security.wrapperDir = lib.mkOption { + type = lib.types.path; + default = "/run/wrappers"; + internal = true; + description = '' + This option defines the path to the wrapper programs. It + should not be overriden. + ''; + }; + }; + + ###### implementation + config = { + # Make sure our setcap-wrapper dir exports to the PATH env + # variable when initializing the shell + environment.extraInit = '' + # The permissions wrappers override other bin directories. + export PATH="${wrapperDir}:$PATH" + ''; + + ###### setcap activation script + system.activationScripts.wrappers = + let + programs = + (map (x: { program = x; owner = "root"; group = "root"; setuid = true; }) + config.security.setuidPrograms) + ++ lib.mapAttrsToList + (n: v: (if v ? "program" then v else v // {program=n;})) + cfg.wrappers; + + wrapperPrograms = + builtins.map + (s: if (s ? "setuid" && s.setuid == true) || + (s ? "setguid" && s.setguid == true) || + (s ? "permissions") + then mkSetuidProgram s + else if (s ? "capabilities") + then mkSetcapProgram s + else "" + ) programs; + + in lib.stringAfter [ "users" ] + '' + # Look in the system path and in the default profile for + # programs to be wrapped. + WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin + + mkdir -p ${wrapperDir} + wrapperDir=$(mktemp --directory --tmpdir=${wrapperDir} wrappers.XXXXXXXXXX) + chmod a+rx $wrapperDir + + ${lib.concatStringsSep "\n" (builtins.filter isNotNull cfg.wrappers)} + ''; + }; +} diff --git a/nixos/modules/security/permissions-wrappers/permissions-wrapper.c b/nixos/modules/security/wrappers/permissions-wrapper.c similarity index 100% rename from nixos/modules/security/permissions-wrappers/permissions-wrapper.c rename to nixos/modules/security/wrappers/permissions-wrapper.c diff --git a/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix b/nixos/modules/security/wrappers/setcap-wrapper-drv.nix similarity index 92% rename from nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix rename to nixos/modules/security/wrappers/setcap-wrapper-drv.nix index 2ae3067b1b1..03dca5c9f42 100644 --- a/nixos/modules/security/permissions-wrappers/setcap-wrapper-drv.nix +++ b/nixos/modules/security/wrappers/setcap-wrapper-drv.nix @@ -1,7 +1,7 @@ { config, lib, pkgs, ... }: let - cfg = config.security.permissionsWrappers; + cfg = config.security.wrappers; # Produce a shell-code splice intended to be stitched into one of # the build or install phases within the derivation. @@ -12,7 +12,7 @@ let source=/nix/var/nix/profiles/default/bin/${program} fi - gcc -Wall -O2 -DWRAPPER_SETCAP=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.run-permissionsWrapperDir}\" \ + gcc -Wall -O2 -DWRAPPER_SETCAP=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.run-wrapperDir}\" \ -lcap-ng -lcap ${./permissions-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 ''; diff --git a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix b/nixos/modules/security/wrappers/setuid-wrapper-drv.nix similarity index 75% rename from nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix rename to nixos/modules/security/wrappers/setuid-wrapper-drv.nix index 53cce2ff48e..e08ae799bf4 100644 --- a/nixos/modules/security/permissions-wrappers/setuid-wrapper-drv.nix +++ b/nixos/modules/security/wrappers/setuid-wrapper-drv.nix @@ -1,18 +1,18 @@ { config, lib, pkgs, ... }: let - cfg = config.security.permissionsWrappers; + cfg = config.security.wrappers; # Produce a shell-code splice intended to be stitched into one of # the build or install phases within the derivation. mkSetuidWrapper = { program, source ? null, ...}: '' - if ! source=${if source != null then source else "$(readlink -f $(PATH=$PERMISSIONS_WRAPPER_PATH type -tP ${program}))"}; then - # If we can't find the program, fall back to the - # system profile. - source=/nix/var/nix/profiles/default/bin/${program} + if ! source=${if source != null then source else "$(readlink -f $(PATH=$WRAPPER_PATH type -tP ${program}))"}; then + # If we can't find the program, fall back to the + # system profile. + source=/nix/var/nix/profiles/default/bin/${program} fi - gcc -Wall -O2 -DWRAPPER_SETUID=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.run-permissionsWrapperDir}\" \ + gcc -Wall -O2 -DWRAPPER_SETUID=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.run-wrapperDir}\" \ -lcap-ng -lcap ${./permissions-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 ''; diff --git a/nixos/modules/services/logging/logcheck.nix b/nixos/modules/services/logging/logcheck.nix index 86451ec318c..c933c496479 100644 --- a/nixos/modules/services/logging/logcheck.nix +++ b/nixos/modules/services/logging/logcheck.nix @@ -29,8 +29,8 @@ let }; cronJob = '' - @reboot logcheck env PATH=/var/permissions-wrappers:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck -R ${flags} - 2 ${cfg.timeOfDay} * * * logcheck env PATH=/var/permissions-wrappers:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck ${flags} + @reboot logcheck env PATH=/run/wrappers:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck -R ${flags} + 2 ${cfg.timeOfDay} * * * logcheck env PATH=/run/wrappers:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck ${flags} ''; writeIgnoreRule = name: {level, regex, ...}: diff --git a/nixos/modules/services/mail/dovecot.nix b/nixos/modules/services/mail/dovecot.nix index 6b37a8a4ea2..7cea2f75439 100644 --- a/nixos/modules/services/mail/dovecot.nix +++ b/nixos/modules/services/mail/dovecot.nix @@ -13,7 +13,7 @@ let '' base_dir = ${baseDir} protocols = ${concatStringsSep " " cfg.protocols} - sendmail_path = /var/permissions-wrappers/sendmail + sendmail_path = /run/wrappers/sendmail '' (if isNull cfg.sslServerCert then '' diff --git a/nixos/modules/services/mail/exim.nix b/nixos/modules/services/mail/exim.nix index 6dfb8fdef11..71414bddd5d 100644 --- a/nixos/modules/services/mail/exim.nix +++ b/nixos/modules/services/mail/exim.nix @@ -70,7 +70,7 @@ in etc."exim.conf".text = '' exim_user = ${cfg.user} exim_group = ${cfg.group} - exim_path = /var/permissions-wrappers/exim + exim_path = /run/wrappers/exim spool_directory = ${cfg.spoolDir} ${cfg.config} ''; @@ -89,15 +89,7 @@ in gid = config.ids.gids.exim; }; - security.permissionsWrappers.setuid = - [ - { program = "exim"; - source = "${pkgs.exim.out}/bin/exim"; - owner = "root"; - group = "root"; - setuid = true; - } - ]; + security.setuidPrograms = [ "exim" ]; systemd.services.exim = { description = "Exim Mail Daemon"; diff --git a/nixos/modules/services/mail/mail.nix b/nixos/modules/services/mail/mail.nix index e8b16349f1a..aef02eddbe1 100644 --- a/nixos/modules/services/mail/mail.nix +++ b/nixos/modules/services/mail/mail.nix @@ -26,7 +26,7 @@ with lib; config = mkIf (config.services.mail.sendmailSetuidWrapper != null) { - security.permissionsWrappers.setuid = [ config.services.mail.sendmailSetuidWrapper ]; + security.wrappers.setuid = [ config.services.mail.sendmailSetuidWrapper ]; }; diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix index a80565fa280..cd4a5125029 100644 --- a/nixos/modules/services/monitoring/munin.nix +++ b/nixos/modules/services/monitoring/munin.nix @@ -34,7 +34,7 @@ let cap=$(sed -nr 's/.*#%#\s+capabilities\s*=\s*(.+)/\1/p' $file) wrapProgram $file \ - --set PATH "/var/permissions-wrappers:/run/current-system/sw/bin:/run/current-system/sw/bin" \ + --set PATH "/run/wrappers:/run/current-system/sw/bin:/run/current-system/sw/bin" \ --set MUNIN_LIBDIR "${pkgs.munin}/lib" \ --set MUNIN_PLUGSTATE "/var/run/munin" @@ -183,7 +183,7 @@ in mkdir -p /etc/munin/plugins rm -rf /etc/munin/plugins/* - PATH="/var/permissions-wrappers:/run/current-system/sw/bin:/run/current-system/sw/bin" ${pkgs.munin}/sbin/munin-node-configure --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${muninPlugins} --servicedir=/etc/munin/plugins 2>/dev/null | ${pkgs.bash}/bin/bash + PATH="/run/wrappers:/run/current-system/sw/bin:/run/current-system/sw/bin" ${pkgs.munin}/sbin/munin-node-configure --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${muninPlugins} --servicedir=/etc/munin/plugins 2>/dev/null | ${pkgs.bash}/bin/bash ''; serviceConfig = { ExecStart = "${pkgs.munin}/sbin/munin-node --config ${nodeConf} --servicedir /etc/munin/plugins/"; diff --git a/nixos/modules/services/monitoring/smartd.nix b/nixos/modules/services/monitoring/smartd.nix index 99fd5c4d367..af02d73597f 100644 --- a/nixos/modules/services/monitoring/smartd.nix +++ b/nixos/modules/services/monitoring/smartd.nix @@ -124,7 +124,7 @@ in }; mailer = mkOption { - default = "/var/permissions-wrappers/sendmail"; + default = "/run/wrappers/sendmail"; type = types.path; description = '' Sendmail-compatible binary to be used to send the messages. diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix index 884966363b8..8cc8f21851c 100644 --- a/nixos/modules/services/network-filesystems/samba.nix +++ b/nixos/modules/services/network-filesystems/samba.nix @@ -30,7 +30,7 @@ let '' [ global ] security = ${cfg.securityType} - passwd program = /var/permissions-wrappers/passwd %u + passwd program = /run/wrappers/passwd %u pam password change = ${smbToString cfg.syncPasswordsByPam} invalid users = ${smbToString cfg.invalidUsers} diff --git a/nixos/modules/services/networking/gale.nix b/nixos/modules/services/networking/gale.nix index bc9b884f11b..f4c75c17290 100644 --- a/nixos/modules/services/networking/gale.nix +++ b/nixos/modules/services/networking/gale.nix @@ -141,7 +141,7 @@ in setgid = false; }; - security.permissionsWrappers.setuid = [ cfg.setuidWrapper ]; + security.wrappers.setuid = [ cfg.setuidWrapper ]; systemd.services.gale-galed = { description = "Gale messaging daemon"; diff --git a/nixos/modules/services/networking/prayer.nix b/nixos/modules/services/networking/prayer.nix index 67d8cece611..58e6ad8a683 100644 --- a/nixos/modules/services/networking/prayer.nix +++ b/nixos/modules/services/networking/prayer.nix @@ -18,7 +18,7 @@ let var_prefix = "${stateDir}" prayer_user = "${prayerUser}" prayer_group = "${prayerGroup}" - sendmail_path = "/var/permissions-wrappers/sendmail" + sendmail_path = "/run/wrappers/sendmail" use_http_port ${cfg.port} diff --git a/nixos/modules/services/networking/smokeping.nix b/nixos/modules/services/networking/smokeping.nix index 67aa313c860..b7bb55f5508 100644 --- a/nixos/modules/services/networking/smokeping.nix +++ b/nixos/modules/services/networking/smokeping.nix @@ -219,14 +219,14 @@ in type = types.string; default = '' + FPing - binary = ${config.security.permissionsWrapperDir}/fping + binary = ${config.security.wrapperDir}/fping ''; description = "Probe configuration"; }; sendmail = mkOption { type = types.nullOr types.path; default = null; - example = "/var/permissions-wrappers/sendmail"; + example = "/run/wrappers/sendmail"; description = "Use this sendmail compatible script to deliver alerts"; }; smokeMailTemplate = mkOption { @@ -273,21 +273,7 @@ in message = "services.smokeping: sendmail and Mailhost cannot both be enabled."; } ]; - security.permissionsWrappers.setuid = [ - { program = "fping"; - source = "${pkgs.fping}/bin/fping"; - owner = "root"; - group = "root"; - setuid = true; - } - - { program = "fping"; - source = "${pkgs.fping}/bin/fping6"; - owner = "root"; - group = "root"; - setuid = true; - } - ]; + security.setuidPrograms = [ "fping" "fping6" ]; environment.systemPackages = [ pkgs.fping ]; users.extraUsers = singleton { name = cfg.user; diff --git a/nixos/modules/services/scheduling/atd.nix b/nixos/modules/services/scheduling/atd.nix index 9c4f8d59faa..316ab847b34 100644 --- a/nixos/modules/services/scheduling/atd.nix +++ b/nixos/modules/services/scheduling/atd.nix @@ -42,7 +42,7 @@ in config = mkIf cfg.enable { - security.permissionsWrappers.setuid = map (program: { + security.wrappers.setuid = map (program: { inherit program; source = "${pkgs.atd}/bin/${program}"; diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix index e33961658f0..26ce3c98d67 100644 --- a/nixos/modules/services/scheduling/cron.nix +++ b/nixos/modules/services/scheduling/cron.nix @@ -20,7 +20,7 @@ let cronNixosPkg = pkgs.cron.override { # The mail.nix nixos module, if there is any local mail system enabled, # should have sendmail in this path. - sendmailPath = "/var/permissions-wrappers/sendmail"; + sendmailPath = "/run/wrappers/sendmail"; }; allFiles = @@ -61,7 +61,7 @@ in A list of Cron jobs to be appended to the system-wide crontab. See the manual page for crontab for the expected format. If you want to get the results mailed you must setuid - sendmail. See + sendmail. See If neither /var/cron/cron.deny nor /var/cron/cron.allow exist only root will is allowed to have its own crontab file. The /var/cron/cron.deny file @@ -92,21 +92,9 @@ in config = mkMerge [ { services.cron.enable = mkDefault (allFiles != []); } - (mkIf (config.services.cron.enable) { - - security.permissionsWrappers.setuid = - [ - { program = "crontab"; - source = "${pkgs.cronNixosPkg.out}/bin/crontab"; - owner = "root"; - group = "root"; - setuid = true; - } - ]; - + security.setuidPrograms = [ "crontab" ]; environment.systemPackages = [ cronNixosPkg ]; - environment.etc.crontab = { source = pkgs.runCommand "crontabs" { inherit allFiles; preferLocalBuild = true; } '' diff --git a/nixos/modules/services/scheduling/fcron.nix b/nixos/modules/services/scheduling/fcron.nix index 5804f0ee72f..f0de996224f 100644 --- a/nixos/modules/services/scheduling/fcron.nix +++ b/nixos/modules/services/scheduling/fcron.nix @@ -96,7 +96,7 @@ in fcronallow = /etc/fcron.allow fcrondeny = /etc/fcron.deny shell = /bin/sh - sendmail = /var/permissions-wrappers/sendmail + sendmail = /run/wrappers/sendmail editor = /run/current-system/sw/bin/vi ''; target = "fcron.conf"; @@ -106,16 +106,7 @@ in environment.systemPackages = [ pkgs.fcron ]; - security.permissionsWrappers.setuid = - [ - { program = "fcrontab"; - source = "${pkgs.fcron.out}/bin/fcrontab"; - owner = "root"; - group = "root"; - setuid = true; - } - ]; - + security.setuidPrograms = [ "fcrontab" ]; systemd.services.fcron = { description = "fcron daemon"; after = [ "local-fs.target" ]; diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix index d15d5551e34..47fc4426af0 100644 --- a/nixos/modules/services/system/dbus.nix +++ b/nixos/modules/services/system/dbus.nix @@ -38,7 +38,7 @@ let sed -ri "s@/etc/dbus-1/(system|session)-@$out/\1-@" $out/{system,session}.conf sed '${./dbus-system-local.conf.in}' \ - -e 's,@servicehelper@,${config.security.permissionsWrapperDir}/dbus-daemon-launch-helper,g' \ + -e 's,@servicehelper@,${config.security.wrapperDir}/dbus-daemon-launch-helper,g' \ -e 's,@extra@,${systemExtraxml},' \ > "$out/system-local.conf" @@ -114,7 +114,7 @@ in systemd.packages = [ pkgs.dbus.daemon ]; - security.permissionsWrappers.setuid = singleton + security.wrappers.setuid = singleton { program = "dbus-daemon-launch-helper"; source = "${pkgs.dbus.daemon}/libexec/dbus-daemon-launch-helper"; owner = "root"; diff --git a/nixos/modules/services/x11/desktop-managers/enlightenment.nix b/nixos/modules/services/x11/desktop-managers/enlightenment.nix index 9d0ff77c2ae..feee6ba87ec 100644 --- a/nixos/modules/services/x11/desktop-managers/enlightenment.nix +++ b/nixos/modules/services/x11/desktop-managers/enlightenment.nix @@ -62,16 +62,7 @@ in ''; }]; - security.permissionsWrappers.setuid = - [ - { program = "e_freqset"; - source = "${e.enlightenment.out}/bin/e_freqset"; - owner = "root"; - group = "root"; - setuid = true; - } - ]; - + security.setuidPrograms = [ "e_freqset" ]; environment.etc = singleton { source = "${pkgs.xkeyboard_config}/etc/X11/xkb"; target = "X11/xkb"; diff --git a/nixos/modules/services/x11/desktop-managers/kde4.nix b/nixos/modules/services/x11/desktop-managers/kde4.nix index 31d2ebcdf1a..d21a1f28dca 100644 --- a/nixos/modules/services/x11/desktop-managers/kde4.nix +++ b/nixos/modules/services/x11/desktop-managers/kde4.nix @@ -131,7 +131,7 @@ in ''; }; - security.permissionsWrappers.setuid = singleton + security.wrappers.setuid = singleton { program = "kcheckpass"; source = "${kde_workspace}/lib/kde4/libexec/kcheckpass"; owner = "root"; diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix index f886c60793d..a4124aaefa9 100644 --- a/nixos/modules/services/x11/desktop-managers/kde5.nix +++ b/nixos/modules/services/x11/desktop-managers/kde5.nix @@ -68,7 +68,7 @@ in ''; }; - security.permissionsWrappers.setuid = [ + security.wrappers.setuid = [ { program = "kcheckpass"; source = "${kde5.plasma-workspace.out}/lib/libexec/kcheckpass"; diff --git a/nixos/modules/system/boot/stage-2-init.sh b/nixos/modules/system/boot/stage-2-init.sh index 86f552cd3ca..ffc0700806c 100644 --- a/nixos/modules/system/boot/stage-2-init.sh +++ b/nixos/modules/system/boot/stage-2-init.sh @@ -131,10 +131,10 @@ if [ -n "@useHostResolvConf@" -a -e /etc/resolv.conf ]; then cat /etc/resolv.conf | resolvconf -m 1000 -a host fi -# Create /var/permissions-wrappers as a tmpfs. -rm -rf /var/permissions-wrappers -mkdir -m 0755 -p /var/permissions-wrappers -mount -t tmpfs -o "mode=0755" tmpfs /var/permissions-wrappers +# Create /run/wrappers as a tmpfs. +rm -rf /run/wrappers +mkdir -m 0755 -p /run/wrappers +mount -t tmpfs -o "mode=0755" tmpfs /run/wrappers # Log the script output to /dev/kmsg or /run/log/stage-2-init.log. # Only at this point are all the necessary prerequisites ready for these commands. diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 61519c6a3ce..1afcddd915f 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -898,38 +898,23 @@ in # Capabilities won't work unless we have at-least a 4.3 Linux # kernel because we need the ambient capability - security.permissionsWrappers.setcap = mkIf (versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.3") ( - [ - { program = "ping"; - source = "${pkgs.iputils.out}/bin/ping"; - capabilities = "cap_net_raw+p"; - } + security.wrappers = mkIf (versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.3") { + ping = { + source = "${pkgs.iputils.out}/bin/ping"; + capabilities = "cap_net_raw+p"; + }; - { program = "ping6"; - source = "${pkgs.iputils.out}/bin/ping6"; - capabilities = "cap_net_raw+p"; - } - ] - ); + ping6 = { + source = "${pkgs.iputils.out}/bin/ping6"; + capabilities = "cap_net_raw+p"; + }; + }; - # If our linux kernel IS older than 4.3, let's setuid ping and ping6 - security.permissionsWrappers.setuid = mkIf (versionOlder (getVersion config.boot.kernelPackages.kernel) "4.3") ( - [ - { program = "ping"; - source = "${pkgs.iputils.out}/bin/ping"; - owner = "root"; - group = "root"; - setuid = true; - } - - { program = "ping6"; - source = "${pkgs.iputils.out}/bin/ping6"; - owner = "root"; - group = "root"; - setuid = true; - } - ] - ); + # If the linux kernel IS older than 4.3, create setuid wrappers + # for ping and ping6 + security.setuidPrograms = mkIf (versionOlder (getVersion config.boot.kernelPackages.kernel) "4.3") [ + "ping" "ping6" + ]; # Set the host and domain names in the activation script. Don't # clear it if it's not configured in the NixOS configuration, diff --git a/nixos/modules/virtualisation/virtualbox-host.nix b/nixos/modules/virtualisation/virtualbox-host.nix index b3647482f2c..405a630dfa7 100644 --- a/nixos/modules/virtualisation/virtualbox-host.nix +++ b/nixos/modules/virtualisation/virtualbox-host.nix @@ -68,7 +68,7 @@ in boot.extraModulePackages = [ kernelModules ]; environment.systemPackages = [ virtualbox ]; - security.permissionsWrappers.setuid = let + security.wrappers.setuid = let mkSuid = program: { inherit program; source = "${virtualbox}/libexec/virtualbox/${program}"; @@ -99,7 +99,7 @@ in SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh --remove $major $minor" ''; - # Since we lack the right setuid binaries, set up a host-only network by default. + # Since we lack the right setuid/setcap binaries, set up a host-only network by default. } (mkIf cfg.addNetworkInterface { systemd.services."vboxnet0" = { description = "VirtualBox vboxnet0 Interface"; diff --git a/nixos/tests/smokeping.nix b/nixos/tests/smokeping.nix index 7e2d84f4422..5e2d013abc5 100644 --- a/nixos/tests/smokeping.nix +++ b/nixos/tests/smokeping.nix @@ -14,7 +14,7 @@ import ./make-test.nix ({ pkgs, ...} : { mailHost = "127.0.0.2"; probeConfig = '' + FPing - binary = /var/permissions-wrappers/fping + binary = /run/wrappers/fping offset = 0% ''; }; diff --git a/pkgs/applications/editors/sublime3/default.nix b/pkgs/applications/editors/sublime3/default.nix index 0f7d50088a9..1c24ff4737b 100644 --- a/pkgs/applications/editors/sublime3/default.nix +++ b/pkgs/applications/editors/sublime3/default.nix @@ -1,5 +1,5 @@ { fetchurl, stdenv, glib, xorg, cairo, gtk2, pango, makeWrapper, openssl, bzip2, - pkexecPath ? "/var/permissions-wrappers/pkexec", libredirect, + pkexecPath ? "/run/wrappers/pkexec", libredirect, gksuSupport ? false, gksu}: assert stdenv.system == "i686-linux" || stdenv.system == "x86_64-linux"; diff --git a/pkgs/applications/networking/browsers/chromium/default.nix b/pkgs/applications/networking/browsers/chromium/default.nix index dd8fd32adfd..7009cf17fab 100644 --- a/pkgs/applications/networking/browsers/chromium/default.nix +++ b/pkgs/applications/networking/browsers/chromium/default.nix @@ -83,9 +83,9 @@ in stdenv.mkDerivation { ed -v -s "$out/bin/chromium" << EOF 2i - if [ -x "/var/permissions-wrappers/${sandboxExecutableName}" ] + if [ -x "/run/wrappers/${sandboxExecutableName}" ] then - export CHROME_DEVEL_SANDBOX="/var/permissions-wrappers/${sandboxExecutableName}" + export CHROME_DEVEL_SANDBOX="/run/wrappers/${sandboxExecutableName}" else export CHROME_DEVEL_SANDBOX="$sandbox/bin/${sandboxExecutableName}" fi diff --git a/pkgs/applications/networking/instant-messengers/gale/gale-install.in.patch b/pkgs/applications/networking/instant-messengers/gale/gale-install.in.patch index 9a83fc09e4e..4b59f1a376d 100644 --- a/pkgs/applications/networking/instant-messengers/gale/gale-install.in.patch +++ b/pkgs/applications/networking/instant-messengers/gale/gale-install.in.patch @@ -26,7 +26,7 @@ index 50e8ad8..eec0ed2 100644 + is_nixos=no +fi + -+if [ -u /var/permissions-wrappers/gksign ]; then ++if [ -u /run/wrappers/gksign ]; then + cat < -#define EXECUTE CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/start_kdeinit" -+#define EXECUTE "/var/permissions-wrappers/start_kdeinit" ++#define EXECUTE "/run/wrappers/start_kdeinit" #if KDEINIT_OOM_PROTECT diff --git a/pkgs/development/libraries/libgksu/default.nix b/pkgs/development/libraries/libgksu/default.nix index 7da4a900b7e..6d57ca2397e 100644 --- a/pkgs/development/libraries/libgksu/default.nix +++ b/pkgs/development/libraries/libgksu/default.nix @@ -57,8 +57,8 @@ stdenv.mkDerivation rec { # Fix some binary paths sed -i -e 's|/usr/bin/xauth|${xauth}/bin/xauth|g' libgksu/gksu-run-helper.c libgksu/libgksu.c - sed -i -e 's|/usr/bin/sudo|/var/permissions-wrappers/sudo|g' libgksu/libgksu.c - sed -i -e 's|/bin/su\([^d]\)|/var/permissions-wrappers/su\1|g' libgksu/libgksu.c + sed -i -e 's|/usr/bin/sudo|/run/wrappers/sudo|g' libgksu/libgksu.c + sed -i -e 's|/bin/su\([^d]\)|/run/wrappers/su\1|g' libgksu/libgksu.c touch NEWS README ''; diff --git a/pkgs/development/libraries/polkit/default.nix b/pkgs/development/libraries/polkit/default.nix index 0f7106181b8..b2e2ecf0493 100644 --- a/pkgs/development/libraries/polkit/default.nix +++ b/pkgs/development/libraries/polkit/default.nix @@ -5,7 +5,7 @@ let system = "/var/run/current-system/sw"; - setuid = "/var/permissions-wrappers"; #TODO: from config.security.wrapperDir; + setuid = "/run/wrappers"; #TODO: from config.security.wrapperDir; foolVars = { SYSCONF = "/etc"; diff --git a/pkgs/development/tools/unity3d/default.nix b/pkgs/development/tools/unity3d/default.nix index 1fc56b98656..2d4977a3195 100644 --- a/pkgs/development/tools/unity3d/default.nix +++ b/pkgs/development/tools/unity3d/default.nix @@ -94,7 +94,7 @@ in stdenv.mkDerivation rec { unitydir="$out/opt/Unity/Editor" mkdir -p $unitydir mv Editor/* $unitydir - ln -sf /var/permissions-wrappers/${chromium.sandboxExecutableName} $unitydir/chrome-sandbox + ln -sf /run/wrappers/${chromium.sandboxExecutableName} $unitydir/chrome-sandbox mkdir -p $out/share/applications sed "/^Exec=/c\Exec=$out/bin/unity-editor" \ diff --git a/pkgs/os-specific/linux/fuse/default.nix b/pkgs/os-specific/linux/fuse/default.nix index a36934004d2..29bcc58c7c0 100644 --- a/pkgs/os-specific/linux/fuse/default.nix +++ b/pkgs/os-specific/linux/fuse/default.nix @@ -23,7 +23,7 @@ stdenv.mkDerivation rec { # Ensure that FUSE calls the setuid wrapper, not # $out/bin/fusermount. It falls back to calling fusermount in # $PATH, so it should also work on non-NixOS systems. - export NIX_CFLAGS_COMPILE="-DFUSERMOUNT_DIR=\"/var/permissions-wrappers\"" + export NIX_CFLAGS_COMPILE="-DFUSERMOUNT_DIR=\"/run/wrappers\"" sed -e 's@/bin/@${utillinux}/bin/@g' -i lib/mount_util.c sed -e 's@CONFIG_RPATH=/usr/share/gettext/config.rpath@CONFIG_RPATH=${gettext}/share/gettext/config.rpath@' -i makeconf.sh diff --git a/pkgs/os-specific/linux/mdadm/4.nix b/pkgs/os-specific/linux/mdadm/4.nix index abe8632773f..af8e53ec3a2 100644 --- a/pkgs/os-specific/linux/mdadm/4.nix +++ b/pkgs/os-specific/linux/mdadm/4.nix @@ -31,7 +31,7 @@ stdenv.mkDerivation rec { preConfigure = '' sed -e 's@/lib/udev@''${out}/lib/udev@' \ -e 's@ -Werror @ @' \ - -e 's@/usr/sbin/sendmail@/var/permissions-wrappers/sendmail@' -i Makefile + -e 's@/usr/sbin/sendmail@/run/wrappers/sendmail@' -i Makefile ''; meta = { diff --git a/pkgs/os-specific/linux/mdadm/default.nix b/pkgs/os-specific/linux/mdadm/default.nix index 531d55a7f12..d9bdf21723b 100644 --- a/pkgs/os-specific/linux/mdadm/default.nix +++ b/pkgs/os-specific/linux/mdadm/default.nix @@ -31,7 +31,7 @@ stdenv.mkDerivation rec { preConfigure = '' sed -e 's@/lib/udev@''${out}/lib/udev@' \ -e 's@ -Werror @ @' \ - -e 's@/usr/sbin/sendmail@/var/permissions-wrappers/sendmail@' -i Makefile + -e 's@/usr/sbin/sendmail@/run/wrappers/sendmail@' -i Makefile ''; meta = { diff --git a/pkgs/os-specific/linux/pam/default.nix b/pkgs/os-specific/linux/pam/default.nix index 196af58183f..dc61b3f27f6 100644 --- a/pkgs/os-specific/linux/pam/default.nix +++ b/pkgs/os-specific/linux/pam/default.nix @@ -34,7 +34,7 @@ stdenv.mkDerivation rec { postInstall = '' mv -v $out/sbin/unix_chkpwd{,.orig} - ln -sv /var/permissions-wrappers/unix_chkpwd $out/sbin/unix_chkpwd + ln -sv /run/wrappers/unix_chkpwd $out/sbin/unix_chkpwd ''; /* rm -rf $out/etc mkdir -p $modules/lib diff --git a/pkgs/os-specific/linux/util-linux/default.nix b/pkgs/os-specific/linux/util-linux/default.nix index 1c4a7b798ce..90fbf861448 100644 --- a/pkgs/os-specific/linux/util-linux/default.nix +++ b/pkgs/os-specific/linux/util-linux/default.nix @@ -36,7 +36,7 @@ stdenv.mkDerivation rec { --enable-last --enable-mesg --disable-use-tty-group - --enable-fs-paths-default=/var/permissions-wrappers:/var/run/current-system/sw/bin:/sbin + --enable-fs-paths-default=/run/wrappers:/var/run/current-system/sw/bin:/sbin ${if ncurses == null then "--without-ncurses" else ""} ${if systemd == null then "" else '' --with-systemd diff --git a/pkgs/servers/interlock/default.nix b/pkgs/servers/interlock/default.nix index af733540ff3..b58c1b50e03 100644 --- a/pkgs/servers/interlock/default.nix +++ b/pkgs/servers/interlock/default.nix @@ -30,7 +30,7 @@ buildGoPackage rec { -e 's|/bin/chown|${coreutils}/bin/chown|' \ -e 's|/bin/date|${coreutils}/bin/date|' \ -e 's|/sbin/poweroff|${systemd}/sbin/poweroff|' \ - -e 's|/usr/bin/sudo|/var/permissions-wrappers/sudo|' \ + -e 's|/usr/bin/sudo|/run/wrappers/sudo|' \ -e 's|/sbin/cryptsetup|${cryptsetup}/bin/cryptsetup|' ''; } diff --git a/pkgs/servers/mail/petidomo/default.nix b/pkgs/servers/mail/petidomo/default.nix index c112af567fd..1770517047f 100644 --- a/pkgs/servers/mail/petidomo/default.nix +++ b/pkgs/servers/mail/petidomo/default.nix @@ -1,4 +1,4 @@ -{ stdenv, fetchurl, flex, bison, sendmailPath ? "/var/permissions-wrappers/sendmail" }: +{ stdenv, fetchurl, flex, bison, sendmailPath ? "/run/wrappers/sendmail" }: stdenv.mkDerivation rec { name = "petidomo-4.3"; diff --git a/pkgs/servers/monitoring/nagios/plugins/official-2.x.nix b/pkgs/servers/monitoring/nagios/plugins/official-2.x.nix index ac1cb1a5398..30bd7e8a7c3 100644 --- a/pkgs/servers/monitoring/nagios/plugins/official-2.x.nix +++ b/pkgs/servers/monitoring/nagios/plugins/official-2.x.nix @@ -16,8 +16,8 @@ stdenv.mkDerivation rec { # configured on the build machine). preConfigure= " configureFlagsArray=( - --with-ping-command='/var/permissions-wrappers/ping -n -U -w %d -c %d %s' - --with-ping6-command='/var/permissions-wrappers/ping6 -n -U -w %d -c %d %s' + --with-ping-command='/run/wrappers/ping -n -U -w %d -c %d %s' + --with-ping6-command='/run/wrappers/ping6 -n -U -w %d -c %d %s' ) "; diff --git a/pkgs/tools/X11/x11vnc/default.nix b/pkgs/tools/X11/x11vnc/default.nix index 5f96a35af6f..b343a7da378 100644 --- a/pkgs/tools/X11/x11vnc/default.nix +++ b/pkgs/tools/X11/x11vnc/default.nix @@ -20,10 +20,10 @@ stdenv.mkDerivation rec { configureFlags="--mandir=$out/share/man" substituteInPlace x11vnc/unixpw.c \ - --replace '"/bin/su"' '"/var/permissions-wrappers/su"' \ + --replace '"/bin/su"' '"/run/wrappers/su"' \ --replace '"/bin/true"' '"${coreutils}/bin/true"' - sed -i -e '/#!\/bin\/sh/a"PATH=${xorg.xdpyinfo}\/bin:${xorg.xauth}\/bin:$PATH\\n"' -e 's|/bin/su|/var/permissions-wrappers/su|g' x11vnc/ssltools.h + sed -i -e '/#!\/bin\/sh/a"PATH=${xorg.xdpyinfo}\/bin:${xorg.xauth}\/bin:$PATH\\n"' -e 's|/bin/su|/run/wrappers/su|g' x11vnc/ssltools.h ''; meta = { diff --git a/pkgs/tools/admin/certbot/default.nix b/pkgs/tools/admin/certbot/default.nix index 23eb02e294a..366213d2e1e 100644 --- a/pkgs/tools/admin/certbot/default.nix +++ b/pkgs/tools/admin/certbot/default.nix @@ -31,7 +31,7 @@ python2Packages.buildPythonApplication rec { buildInputs = [ dialog ] ++ (with python2Packages; [ nose mock gnureadline ]); patchPhase = '' - substituteInPlace certbot/notify.py --replace "/usr/sbin/sendmail" "/var/permissions-wrappers/sendmail" + substituteInPlace certbot/notify.py --replace "/usr/sbin/sendmail" "/run/wrappers/sendmail" substituteInPlace certbot/util.py --replace "sw_vers" "/usr/bin/sw_vers" ''; diff --git a/pkgs/tools/misc/debian-devscripts/default.nix b/pkgs/tools/misc/debian-devscripts/default.nix index 2261bfc6637..be3b674de04 100644 --- a/pkgs/tools/misc/debian-devscripts/default.nix +++ b/pkgs/tools/misc/debian-devscripts/default.nix @@ -2,7 +2,7 @@ , FileDesktopEntry, libxslt, docbook_xsl, makeWrapper , python3Packages , perlPackages, curl, gnupg, diffutils -, sendmailPath ? "/var/permissions-wrappers/sendmail" +, sendmailPath ? "/run/wrappers/sendmail" }: let diff --git a/pkgs/tools/security/ecryptfs/default.nix b/pkgs/tools/security/ecryptfs/default.nix index 7e941e5378a..98e06d1de3e 100644 --- a/pkgs/tools/security/ecryptfs/default.nix +++ b/pkgs/tools/security/ecryptfs/default.nix @@ -11,7 +11,7 @@ stdenv.mkDerivation rec { }; # TODO: replace wrapperDir below with from config.security.wrapperDir; - wrapperDir = "/var/permissions-wrappers"; + wrapperDir = "/run/wrappers"; postPatch = '' FILES="$(grep -r '/bin/sh' src/utils -l; find src -name \*.c)" diff --git a/pkgs/tools/security/ecryptfs/helper.nix b/pkgs/tools/security/ecryptfs/helper.nix index 6e3e6766a28..3daaadcaad6 100644 --- a/pkgs/tools/security/ecryptfs/helper.nix +++ b/pkgs/tools/security/ecryptfs/helper.nix @@ -18,7 +18,7 @@ stdenv.mkDerivation rec { buildInputs = [ makeWrapper ]; - # Do not hardcode PATH to ${ecryptfs} as we need the script to invoke executables from /var/permissions-wrappers + # Do not hardcode PATH to ${ecryptfs} as we need the script to invoke executables from /run/wrappers installPhase = '' mkdir -p $out/bin $out/libexec cp $src $out/libexec/ecryptfs-helper.py diff --git a/pkgs/tools/security/sudo/default.nix b/pkgs/tools/security/sudo/default.nix index a3a13f19803..0d2953c6f45 100644 --- a/pkgs/tools/security/sudo/default.nix +++ b/pkgs/tools/security/sudo/default.nix @@ -1,5 +1,5 @@ { stdenv, fetchurl, coreutils, pam, groff -, sendmailPath ? "/var/permissions-wrappers/sendmail" +, sendmailPath ? "/run/wrappers/sendmail" , withInsults ? false }: diff --git a/pkgs/tools/system/at/default.nix b/pkgs/tools/system/at/default.nix index 2fb5b9670c8..9f8bad00ca4 100644 --- a/pkgs/tools/system/at/default.nix +++ b/pkgs/tools/system/at/default.nix @@ -1,4 +1,4 @@ -{ fetchurl, stdenv, bison, flex, pam, sendmailPath ? "/var/permissions-wrappers/sendmail" }: +{ fetchurl, stdenv, bison, flex, pam, sendmailPath ? "/run/wrappers/sendmail" }: stdenv.mkDerivation { name = "at-3.1.16"; diff --git a/pkgs/tools/system/cron/default.nix b/pkgs/tools/system/cron/default.nix index f7f2a6158a2..8a6a5dc15d3 100644 --- a/pkgs/tools/system/cron/default.nix +++ b/pkgs/tools/system/cron/default.nix @@ -23,7 +23,7 @@ stdenv.mkDerivation { #define _PATH_SENDMAIL "${sendmailPath}" #undef _PATH_DEFPATH - #define _PATH_DEFPATH "/var/permissions-wrappers:/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/run/current-system/sw/bin:/run/current-system/sw/sbin:/usr/bin:/bin" + #define _PATH_DEFPATH "/run/wrappers:/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/run/current-system/sw/bin:/run/current-system/sw/sbin:/usr/bin:/bin" __EOT__ # Implicit saved uids do not work here due to way NixOS uses setuid wrappers diff --git a/pkgs/tools/system/ts/default.nix b/pkgs/tools/system/ts/default.nix index 1384ea04fb6..1dfb856d4d6 100644 --- a/pkgs/tools/system/ts/default.nix +++ b/pkgs/tools/system/ts/default.nix @@ -1,5 +1,5 @@ {stdenv, fetchurl, -sendmailPath ? "/var/permissions-wrappers/sendmail" }: +sendmailPath ? "/run/wrappers/sendmail" }: stdenv.mkDerivation rec { From 3fe7b1a4c97ef0a098c0cd786386e2b547762983 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 01:07:12 -0600 Subject: [PATCH 38/74] setcap-wrapper: Addressing more PR feedback, unifying drvs, and cleaning up a bit --- nixos/modules/security/wrappers/default.nix | 58 +++++++++++-------- .../security/wrappers/permissions-wrapper.c | 25 ++++---- .../security/wrappers/setcap-wrapper-drv.nix | 37 ------------ .../security/wrappers/setuid-wrapper-drv.nix | 35 ----------- 4 files changed, 46 insertions(+), 109 deletions(-) delete mode 100644 nixos/modules/security/wrappers/setcap-wrapper-drv.nix delete mode 100644 nixos/modules/security/wrappers/setuid-wrapper-drv.nix diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index d12209b375b..69b62d7b2ff 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -3,17 +3,27 @@ let inherit (config.security) wrapperDir; - isNotNull = v: if v != null || v != "" then true else false; + wrappers = config.security.wrappers; + mkWrapper = { program, source ? null, ...}: '' + if ! source=${if source != null then source else "$(readlink -f $(PATH=$WRAPPER_PATH type -tP ${program}))"}; then + # If we can't find the program, fall back to the + # system profile. + source=/nix/var/nix/profiles/default/bin/${program} + fi - cfg = config.security.wrappers; + gcc -Wall -O2 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.wrapperDir}\" \ + -lcap-ng -lcap ${./permissions-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 + ''; - setcapWrappers = import ./setcap-wrapper-drv.nix { - inherit config lib pkgs; - }; - - setuidWrappers = import ./setuid-wrapper-drv.nix { - inherit config lib pkgs; - }; + wrappedPrograms = pkgs.stdenv.mkDerivation { + name = "permissions-wrapper"; + unpackPhase = "true"; + installPhase = '' + mkdir -p $out/bin + ${lib.concatMapStrings mkWrapper wrappers} + ''; + } ###### Activation script for the setcap wrappers mkSetcapProgram = @@ -23,8 +33,10 @@ let , owner ? "nobody" , group ? "nogroup" ... - }: '' - cp ${setcapWrappers}/bin/${program}.wrapper $wrapperDir/${program} + }: + assert (lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3"); + '' + cp ${wrappedPrograms}/bin/${program}.wrapper $wrapperDir/${program} # Prevent races chmod 0000 $wrapperDir/${program} @@ -33,9 +45,6 @@ let # Set desired capabilities on the file plus cap_setpcap so # the wrapper program can elevate the capabilities set on # its file into the Ambient set. - # - # Only set the capabilities though if we're being told to - # do so. ${pkgs.libcap.out}/bin/setcap "cap_setpcap,${capabilities}" $wrapperDir/${program} # Set the executable bit @@ -53,7 +62,7 @@ let , permissions ? "u+rx,g+x,o+x" ... }: '' - cp ${setuidWrappers}/bin/${program}.wrapper $wrapperDir/${program} + cp ${wrappedPrograms}/bin/${program}.wrapper $wrapperDir/${program} # Prevent races chmod 0000 $wrapperDir/${program} @@ -147,10 +156,10 @@ in ###### implementation config = { - # Make sure our setcap-wrapper dir exports to the PATH env - # variable when initializing the shell + # Make sure our wrapperDir exports to the PATH env variable when + # initializing the shell environment.extraInit = '' - # The permissions wrappers override other bin directories. + # Wrappers override other bin directories. export PATH="${wrapperDir}:$PATH" ''; @@ -162,16 +171,17 @@ in config.security.setuidPrograms) ++ lib.mapAttrsToList (n: v: (if v ? "program" then v else v // {program=n;})) - cfg.wrappers; + wrappers; - wrapperPrograms = + mkWrappedPrograms = builtins.map - (s: if (s ? "setuid" && s.setuid == true) || + (s: if (s ? "capabilities") + then mkSetcapProgram s + else if + (s ? "setuid" && s.setuid == true) || (s ? "setguid" && s.setguid == true) || (s ? "permissions") then mkSetuidProgram s - else if (s ? "capabilities") - then mkSetcapProgram s else "" ) programs; @@ -185,7 +195,7 @@ in wrapperDir=$(mktemp --directory --tmpdir=${wrapperDir} wrappers.XXXXXXXXXX) chmod a+rx $wrapperDir - ${lib.concatStringsSep "\n" (builtins.filter isNotNull cfg.wrappers)} + ${lib.concatStringsSep "\n" mkWrappedPrograms} ''; }; } diff --git a/nixos/modules/security/wrappers/permissions-wrapper.c b/nixos/modules/security/wrappers/permissions-wrapper.c index cb9d8d6b37b..608bd3a378c 100644 --- a/nixos/modules/security/wrappers/permissions-wrapper.c +++ b/nixos/modules/security/wrappers/permissions-wrapper.c @@ -26,16 +26,6 @@ extern char **environ; static char * sourceProg = SOURCE_PROG; static char * wrapperDir = WRAPPER_DIR; -// Make sure we have the WRAPPER_TYPE macro specified at compile -// time... -#ifdef WRAPPER_SETCAP -static char * wrapperType = "setcap"; -#elif defined WRAPPER_SETUID -static char * wrapperType = "setuid"; -#else -#error "Program must be compiled with either the WRAPPER_SETCAP or WRAPPER_SETUID macro" -#endif - // Update the capabilities of the running process to include the given // capability in the Ambient set. static void set_ambient_cap(cap_value_t cap) @@ -66,7 +56,7 @@ static int make_caps_ambient(const char *selfPath) if(!caps) { - fprintf(stderr, "could not retreive the capability set for this file\n"); + fprintf(stderr, "no caps set or could not retrieve the caps for this file, not doing anything...\n"); return 1; } @@ -171,6 +161,16 @@ int main(int argc, char * * argv) assert(selfPathSize > 0); + // Assert we have room for the zero byte, this ensures the path + // isn't being truncated because it's too big for the buffer. + // + // A better way to handle this might be to use something like the + // whereami library (https://github.com/gpakosz/whereami) or a + // loop that resizes the buffer and re-reads the link if the + // contents are being truncated. + assert(selfPathSize < sizeof(selfPath)); + + // Set the zero byte since readlink doesn't do that for us. selfPath[selfPathSize] = '\0'; // Make sure that we are being executed from the right location, @@ -207,8 +207,7 @@ int main(int argc, char * * argv) // Read the capabilities set on the file and raise them in to the // Ambient set so the program we're wrapping receives the // capabilities too! - if (strcmp(wrapperType, "setcap") == 0) - assert(!make_caps_ambient(selfPath)); + make_caps_ambient(selfPath); execve(sourceProg, argv, environ); diff --git a/nixos/modules/security/wrappers/setcap-wrapper-drv.nix b/nixos/modules/security/wrappers/setcap-wrapper-drv.nix deleted file mode 100644 index 03dca5c9f42..00000000000 --- a/nixos/modules/security/wrappers/setcap-wrapper-drv.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ config, lib, pkgs, ... }: - -let - cfg = config.security.wrappers; - - # Produce a shell-code splice intended to be stitched into one of - # the build or install phases within the derivation. - mkSetcapWrapper = { program, source ? null, ...}: '' - if ! source=${if source != null then source else "$(readlink -f $(PATH=$PERMISSIONS_WRAPPER_PATH type -tP ${program}))"}; then - # If we can't find the program, fall back to the - # system profile. - source=/nix/var/nix/profiles/default/bin/${program} - fi - - gcc -Wall -O2 -DWRAPPER_SETCAP=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.run-wrapperDir}\" \ - -lcap-ng -lcap ${./permissions-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 - -# This is only useful for Linux platforms and a kernel version of -# 4.3 or greater -assert pkgs.stdenv.isLinux; -assert lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3"; - -pkgs.stdenv.mkDerivation { - name = "setcap-wrapper"; - unpackPhase = "true"; - buildInputs = [ pkgs.linuxHeaders ]; - installPhase = '' - mkdir -p $out/bin - - # Concat together all of our shell splices to compile - # binary wrapper programs for all configured setcap programs. - ${lib.concatMapStrings mkSetcapWrapper cfg.setcap} - ''; -} diff --git a/nixos/modules/security/wrappers/setuid-wrapper-drv.nix b/nixos/modules/security/wrappers/setuid-wrapper-drv.nix deleted file mode 100644 index e08ae799bf4..00000000000 --- a/nixos/modules/security/wrappers/setuid-wrapper-drv.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ config, lib, pkgs, ... }: - -let - cfg = config.security.wrappers; - - # Produce a shell-code splice intended to be stitched into one of - # the build or install phases within the derivation. - mkSetuidWrapper = { program, source ? null, ...}: '' - if ! source=${if source != null then source else "$(readlink -f $(PATH=$WRAPPER_PATH type -tP ${program}))"}; then - # If we can't find the program, fall back to the - # system profile. - source=/nix/var/nix/profiles/default/bin/${program} - fi - - gcc -Wall -O2 -DWRAPPER_SETUID=1 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.run-wrapperDir}\" \ - -lcap-ng -lcap ${./permissions-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 - -# This is only useful for Linux platforms and a kernel version of -# 4.3 or greater -assert pkgs.stdenv.isLinux; - -pkgs.stdenv.mkDerivation { - name = "setuid-wrapper"; - unpackPhase = "true"; - installPhase = '' - mkdir -p $out/bin - - # Concat together all of our shell splices to compile - # binary wrapper programs for all configured setcap programs. - ${lib.concatMapStrings mkSetuidWrapper cfg.setuid} - ''; -} From 2f113ee90a8c97be2ccb70dc6738fe243dde1b84 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 01:08:36 -0600 Subject: [PATCH 39/74] setcap-wrapper: Minor refactor --- nixos/modules/security/wrappers/default.nix | 2 +- .../security/wrappers/{permissions-wrapper.c => wrapper.c} | 0 .../sniffers/wireshark/wireshark-lookup-dumpcap-in-path.patch | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename nixos/modules/security/wrappers/{permissions-wrapper.c => wrapper.c} (100%) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 69b62d7b2ff..4d51796b676 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -12,7 +12,7 @@ let fi gcc -Wall -O2 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.wrapperDir}\" \ - -lcap-ng -lcap ${./permissions-wrapper.c} -o $out/bin/${program}.wrapper -L ${pkgs.libcap.lib}/lib -L ${pkgs.libcap_ng}/lib \ + -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 ''; diff --git a/nixos/modules/security/wrappers/permissions-wrapper.c b/nixos/modules/security/wrappers/wrapper.c similarity index 100% rename from nixos/modules/security/wrappers/permissions-wrapper.c rename to nixos/modules/security/wrappers/wrapper.c diff --git a/pkgs/applications/networking/sniffers/wireshark/wireshark-lookup-dumpcap-in-path.patch b/pkgs/applications/networking/sniffers/wireshark/wireshark-lookup-dumpcap-in-path.patch index 3d38cf3b604..549da5436e6 100644 --- a/pkgs/applications/networking/sniffers/wireshark/wireshark-lookup-dumpcap-in-path.patch +++ b/pkgs/applications/networking/sniffers/wireshark/wireshark-lookup-dumpcap-in-path.patch @@ -4,7 +4,7 @@ Date: Thu, 26 Nov 2015 21:03:35 +0100 Subject: [PATCH] Lookup dumpcap in PATH NixOS patch: Look for dumpcap in PATH first, because there may be a -dumpcap permissions-wrapper that we want to use instead of the default +dumpcap wrapper that we want to use instead of the default non-setuid dumpcap binary. Also change execv() to execvp() because we've set argv[0] to "dumpcap" @@ -27,7 +27,7 @@ index 970688e..49914d5 100644 - exename = g_strdup_printf("%s/dumpcap", progfile_dir); + /* + * NixOS patch: Look for dumpcap in PATH first, because there may be a -+ * dumpcap permissions-wrapper that we want to use instead of the default ++ * dumpcap wrapper that we want to use instead of the default + * non-setuid dumpcap binary. + */ + if (system("command -v dumpcap >/dev/null") == 0) { From 7680a40a373a89c683f5b87dfa3cd09c2a168473 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 01:16:04 -0600 Subject: [PATCH 40/74] setcap-wrapper: Syntax wibble --- nixos/modules/security/wrappers/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 4d51796b676..093f2bb49b0 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -23,7 +23,7 @@ let mkdir -p $out/bin ${lib.concatMapStrings mkWrapper wrappers} ''; - } + }; ###### Activation script for the setcap wrappers mkSetcapProgram = From 82de4c0fad9607b9b193564dedf92ac830202eeb Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 01:20:02 -0600 Subject: [PATCH 41/74] setcap-wrapper: Syntax wibble --- nixos/modules/security/wrappers/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 093f2bb49b0..3f1a42c53b7 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -32,7 +32,7 @@ let , source ? null , owner ? "nobody" , group ? "nogroup" - ... + , ... }: assert (lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3"); '' @@ -60,7 +60,7 @@ let , setuid ? false , setgid ? false , permissions ? "u+rx,g+x,o+x" - ... + , ... }: '' cp ${wrappedPrograms}/bin/${program}.wrapper $wrapperDir/${program} From 70ec24093c45a07a5b4f4d230390dfa16e87e1dc Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 01:22:19 -0600 Subject: [PATCH 42/74] Removing dead code --- nixos/modules/security/wrappers/default.nix | 54 +++++++++------------ 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 3f1a42c53b7..3012439e13d 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -76,37 +76,6 @@ in ###### interface options = { - security.wrappers.setcap = lib.mkOption { - type = lib.types.listOf lib.types.attrs; - default = []; - example = - [ { program = "ping"; - source = "${pkgs.iputils.out}/bin/ping"; - owner = "nobody"; - group = "nogroup"; - capabilities = "cap_net_raw+ep"; - } - ]; - description = '' - This option sets capabilities on a wrapper program that - propagates those capabilities down to the wrapped, real - program. - - The program attribute is the name of the - program to be wrapped. If no source - attribute is provided, specifying the absolute path to the - program, then the program will be searched for in the path - environment variable. - - NOTE: cap_setpcap, which is required for the wrapper program - to be able to raise caps into the Ambient set is NOT raised to - the Ambient set so that the real program cannot modify its own - capabilities!! This may be too restrictive for cases in which - the real program needs cap_setpcap but it at least leans on - the side security paranoid vs. too relaxed. - ''; - }; - security.setuidPrograms = mkOption { type = types.listOf types.str; default = []; @@ -125,11 +94,34 @@ in default = {}; example = { sendmail.source = "/nix/store/.../bin/sendmail"; + ping = { + source = "${pkgs.iputils.out}/bin/ping"; + owner = "nobody"; + group = "nogroup"; + capabilities = "cap_net_raw+ep"; + }; }; description = '' This option allows the ownership and permissions on the setuid wrappers for specific programs to be overridden from the default (setuid root, but not setgid root). + + Additionally, this option can set capabilities on a wrapper + program that propagates those capabilities down to the + wrapped, real program. + + The program attribute is the name of the + program to be wrapped. If no source + attribute is provided, specifying the absolute path to the + program, then the program will be searched for in the path + environment variable. + + NOTE: cap_setpcap, which is required for the wrapper program + to be able to raise caps into the Ambient set is NOT raised to + the Ambient set so that the real program cannot modify its own + capabilities!! This may be too restrictive for cases in which + the real program needs cap_setpcap but it at least leans on + the side security paranoid vs. too relaxed. ''; }; From 8e159b9d1ed816abca9ca415aba0bc254c4e162c Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 01:22:47 -0600 Subject: [PATCH 43/74] Qualify mkOption with lib --- nixos/modules/security/wrappers/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 3012439e13d..fa371283706 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -76,7 +76,7 @@ in ###### interface options = { - security.setuidPrograms = mkOption { + security.setuidPrograms = lib.mkOption { type = types.listOf types.str; default = []; example = ["passwd"]; From 0707a3eaa2ce33e8f490fff474c168a33dc1b5f5 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 01:23:10 -0600 Subject: [PATCH 44/74] Qualify with lib --- nixos/modules/security/wrappers/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index fa371283706..b71e3d21985 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -77,7 +77,7 @@ in options = { security.setuidPrograms = lib.mkOption { - type = types.listOf types.str; + type = lib.types.listOf lib.types.str; default = []; example = ["passwd"]; description = '' From 5077699605fae8840afe1a066a37412e7ea9206f Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 01:27:11 -0600 Subject: [PATCH 45/74] Derp derp --- nixos/modules/security/wrappers/default.nix | 46 ++++++++++----------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index b71e3d21985..a93db916fad 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -1,9 +1,15 @@ { config, lib, pkgs, ... }: let - inherit (config.security) wrapperDir; + inherit (config.security) wrapperDir wrappers setuidPrograms; + + programs = + (map (x: { program = x; owner = "root"; group = "root"; setuid = true; }) + setuidPrograms) + ++ lib.mapAttrsToList + (n: v: (if v ? "program" then v else v // {program=n;})) + wrappers; - wrappers = config.security.wrappers; mkWrapper = { program, source ? null, ...}: '' if ! source=${if source != null then source else "$(readlink -f $(PATH=$WRAPPER_PATH type -tP ${program}))"}; then # If we can't find the program, fall back to the @@ -21,7 +27,7 @@ let unpackPhase = "true"; installPhase = '' mkdir -p $out/bin - ${lib.concatMapStrings mkWrapper wrappers} + ${lib.concatMapStrings (builtins.map mkWrapper programs)} ''; }; @@ -70,6 +76,18 @@ let chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" $wrapperDir/${program} ''; + + mkWrappedPrograms = + builtins.map + (s: if (s ? "capabilities") + then mkSetcapProgram s + else if + (s ? "setuid" && s.setuid == true) || + (s ? "setguid" && s.setguid == true) || + (s ? "permissions") + then mkSetuidProgram s + else "" + ) programs; in { @@ -157,27 +175,7 @@ in ###### setcap activation script system.activationScripts.wrappers = - let - programs = - (map (x: { program = x; owner = "root"; group = "root"; setuid = true; }) - config.security.setuidPrograms) - ++ lib.mapAttrsToList - (n: v: (if v ? "program" then v else v // {program=n;})) - wrappers; - - mkWrappedPrograms = - builtins.map - (s: if (s ? "capabilities") - then mkSetcapProgram s - else if - (s ? "setuid" && s.setuid == true) || - (s ? "setguid" && s.setguid == true) || - (s ? "permissions") - then mkSetuidProgram s - else "" - ) programs; - - in lib.stringAfter [ "users" ] + lib.stringAfter [ "users" ] '' # Look in the system path and in the default profile for # programs to be wrapped. From 48564d1ae56b93a27ca6dc5565f389dfde66831a Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 01:31:33 -0600 Subject: [PATCH 46/74] Another wibble --- nixos/modules/security/wrappers/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index a93db916fad..28aacb891ee 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -27,7 +27,7 @@ let unpackPhase = "true"; installPhase = '' mkdir -p $out/bin - ${lib.concatMapStrings (builtins.map mkWrapper programs)} + ${lib.concatMapStrings mkWrapper programs} ''; }; From af3b9a3d46672232d70e4ab6a45f00e10363bfae Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 01:41:39 -0600 Subject: [PATCH 47/74] More wibbles? --- nixos/modules/security/wrappers/default.nix | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 28aacb891ee..0170da03689 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -4,11 +4,11 @@ let inherit (config.security) wrapperDir wrappers setuidPrograms; programs = - (map (x: { program = x; owner = "root"; group = "root"; setuid = true; }) - setuidPrograms) - ++ lib.mapAttrsToList - (n: v: (if v ? "program" then v else v // {program=n;})) - wrappers; + (map (x: { program = x; owner = "root"; group = "root"; setuid = true; }) setuidPrograms) + ++ + (lib.mapAttrsToList + (n: v: (if v ? "program" then v else v // {program=n;})) + wrappers); mkWrapper = { program, source ? null, ...}: '' if ! source=${if source != null then source else "$(readlink -f $(PATH=$WRAPPER_PATH type -tP ${program}))"}; then From a8cb2afa981099889cf47185be33f4a831ff482b Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 01:58:12 -0600 Subject: [PATCH 48/74] Fixing a bunch of issues --- nixos/modules/services/mail/mail.nix | 2 +- nixos/modules/services/networking/gale.nix | 2 +- nixos/modules/services/scheduling/atd.nix | 4 +--- nixos/modules/services/scheduling/cron.nix | 2 +- nixos/modules/services/system/dbus.nix | 17 ++++++++--------- .../services/x11/desktop-managers/kde4.nix | 8 +------- .../services/x11/desktop-managers/kde5.nix | 18 ++++-------------- .../modules/virtualisation/virtualbox-host.nix | 5 ++--- 8 files changed, 19 insertions(+), 39 deletions(-) diff --git a/nixos/modules/services/mail/mail.nix b/nixos/modules/services/mail/mail.nix index aef02eddbe1..cfe1b5496a4 100644 --- a/nixos/modules/services/mail/mail.nix +++ b/nixos/modules/services/mail/mail.nix @@ -26,7 +26,7 @@ with lib; config = mkIf (config.services.mail.sendmailSetuidWrapper != null) { - security.wrappers.setuid = [ config.services.mail.sendmailSetuidWrapper ]; + security.wrappers.sendmail = config.services.mail.sendmailSetuidWrapper; }; diff --git a/nixos/modules/services/networking/gale.nix b/nixos/modules/services/networking/gale.nix index f4c75c17290..fd83f9e3c1b 100644 --- a/nixos/modules/services/networking/gale.nix +++ b/nixos/modules/services/networking/gale.nix @@ -141,7 +141,7 @@ in setgid = false; }; - security.wrappers.setuid = [ cfg.setuidWrapper ]; + security.wrappers.gksign = cfg.setuidWrapper; systemd.services.gale-galed = { description = "Gale messaging daemon"; diff --git a/nixos/modules/services/scheduling/atd.nix b/nixos/modules/services/scheduling/atd.nix index 316ab847b34..7b4937b5c67 100644 --- a/nixos/modules/services/scheduling/atd.nix +++ b/nixos/modules/services/scheduling/atd.nix @@ -42,9 +42,7 @@ in config = mkIf cfg.enable { - security.wrappers.setuid = map (program: { - inherit program; - + security.wrappers.setuid = map (program: "${program}" = { source = "${pkgs.atd}/bin/${program}"; owner = "atd"; group = "atd"; diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix index 26ce3c98d67..7bd1e481804 100644 --- a/nixos/modules/services/scheduling/cron.nix +++ b/nixos/modules/services/scheduling/cron.nix @@ -61,7 +61,7 @@ in A list of Cron jobs to be appended to the system-wide crontab. See the manual page for crontab for the expected format. If you want to get the results mailed you must setuid - sendmail. See + sendmail. See If neither /var/cron/cron.deny nor /var/cron/cron.allow exist only root will is allowed to have its own crontab file. The /var/cron/cron.deny file diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix index 47fc4426af0..f787c02540d 100644 --- a/nixos/modules/services/system/dbus.nix +++ b/nixos/modules/services/system/dbus.nix @@ -114,15 +114,14 @@ in systemd.packages = [ pkgs.dbus.daemon ]; - security.wrappers.setuid = singleton - { program = "dbus-daemon-launch-helper"; - source = "${pkgs.dbus.daemon}/libexec/dbus-daemon-launch-helper"; - owner = "root"; - group = "messagebus"; - setuid = true; - setgid = false; - permissions = "u+rx,g+rx,o-rx"; - }; + security.wrappers.dbus-daemon-launch-helper = { + source = "${pkgs.dbus.daemon}/libexec/dbus-daemon-launch-helper"; + owner = "root"; + group = "messagebus"; + setuid = true; + setgid = false; + permissions = "u+rx,g+rx,o-rx"; + }; services.dbus.packages = [ pkgs.dbus.out diff --git a/nixos/modules/services/x11/desktop-managers/kde4.nix b/nixos/modules/services/x11/desktop-managers/kde4.nix index d21a1f28dca..25ae75592c9 100644 --- a/nixos/modules/services/x11/desktop-managers/kde4.nix +++ b/nixos/modules/services/x11/desktop-managers/kde4.nix @@ -131,13 +131,7 @@ in ''; }; - security.wrappers.setuid = singleton - { program = "kcheckpass"; - source = "${kde_workspace}/lib/kde4/libexec/kcheckpass"; - owner = "root"; - group = "root"; - setuid = true; - }; + security.wrappers.kcheckpass.source = "${kde_workspace}/lib/kde4/libexec/kcheckpass"; environment.systemPackages = [ pkgs.kde4.kdelibs diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix index a4124aaefa9..00fdfedbc7b 100644 --- a/nixos/modules/services/x11/desktop-managers/kde5.nix +++ b/nixos/modules/services/x11/desktop-managers/kde5.nix @@ -68,20 +68,10 @@ in ''; }; - security.wrappers.setuid = [ - { - program = "kcheckpass"; - source = "${kde5.plasma-workspace.out}/lib/libexec/kcheckpass"; - owner = "root"; - setuid = true; - } - { - program = "start_kdeinit"; - source = "${kde5.kinit.out}/lib/libexec/kf5/start_kdeinit"; - owner = "root"; - setuid = true; - } - ]; + security.wrappers = { + kcheckpass.source = "${kde5.plasma-workspace.out}/lib/libexec/kcheckpass"; + "start_kdeinit".source = "${kde5.kinit.out}/lib/libexec/kf5/start_kdeinit"; + }; environment.systemPackages = [ diff --git a/nixos/modules/virtualisation/virtualbox-host.nix b/nixos/modules/virtualisation/virtualbox-host.nix index 405a630dfa7..70ee44680ab 100644 --- a/nixos/modules/virtualisation/virtualbox-host.nix +++ b/nixos/modules/virtualisation/virtualbox-host.nix @@ -68,9 +68,8 @@ in boot.extraModulePackages = [ kernelModules ]; environment.systemPackages = [ virtualbox ]; - security.wrappers.setuid = let - mkSuid = program: { - inherit program; + security.wrappers = let + mkSuid = program: "${program}" = { source = "${virtualbox}/libexec/virtualbox/${program}"; owner = "root"; group = "vboxusers"; From 4aa0923009dac4d2307b5fe018b944180bfad6a2 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 04:11:01 -0600 Subject: [PATCH 49/74] Getting rid of the var indirection and using a bin path instead --- .../modules/installer/tools/nixos-install.sh | 4 +-- nixos/modules/security/apparmor-suid.nix | 3 +- nixos/modules/security/wrappers/default.nix | 33 +++++++++++++++++-- nixos/modules/services/logging/logcheck.nix | 4 +-- nixos/modules/services/mail/dovecot.nix | 2 +- nixos/modules/services/mail/exim.nix | 2 +- nixos/modules/services/monitoring/munin.nix | 4 +-- nixos/modules/services/monitoring/smartd.nix | 2 +- .../services/network-filesystems/samba.nix | 2 +- nixos/modules/services/networking/prayer.nix | 2 +- .../modules/services/networking/smokeping.nix | 2 +- nixos/modules/services/scheduling/atd.nix | 4 +-- nixos/modules/services/scheduling/cron.nix | 2 +- nixos/modules/services/scheduling/fcron.nix | 2 +- nixos/modules/system/boot/stage-2-init.sh | 5 --- .../virtualisation/virtualbox-host.nix | 4 +-- nixos/tests/smokeping.nix | 2 +- .../applications/editors/sublime3/default.nix | 2 +- .../networking/browsers/chromium/default.nix | 4 +-- .../gale/gale-install.in.patch | 2 +- .../gitlab/remove-hardcoded-locations.patch | 2 +- .../virtualization/virtualbox/hardened.patch | 6 ++-- pkgs/build-support/build-fhs-userenv/env.nix | 2 +- pkgs/desktops/enlightenment/enlightenment.nix | 6 ++-- .../kinit/start_kdeinit-path.patch | 2 +- .../development/libraries/libgksu/default.nix | 4 +-- pkgs/development/libraries/polkit/default.nix | 2 +- pkgs/development/tools/unity3d/default.nix | 2 +- pkgs/os-specific/linux/fuse/default.nix | 2 +- pkgs/os-specific/linux/mdadm/4.nix | 2 +- pkgs/os-specific/linux/mdadm/default.nix | 2 +- pkgs/os-specific/linux/pam/default.nix | 2 +- pkgs/os-specific/linux/util-linux/default.nix | 2 +- pkgs/servers/interlock/default.nix | 2 +- pkgs/servers/mail/petidomo/default.nix | 2 +- .../nagios/plugins/official-2.x.nix | 4 +-- pkgs/tools/X11/x11vnc/default.nix | 4 +-- pkgs/tools/admin/certbot/default.nix | 2 +- pkgs/tools/misc/debian-devscripts/default.nix | 2 +- pkgs/tools/security/ecryptfs/default.nix | 2 +- pkgs/tools/security/ecryptfs/helper.nix | 2 +- pkgs/tools/security/sudo/default.nix | 2 +- pkgs/tools/system/at/default.nix | 2 +- pkgs/tools/system/cron/default.nix | 2 +- pkgs/tools/system/ts/default.nix | 2 +- 45 files changed, 86 insertions(+), 65 deletions(-) diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh index 36b1a47956d..57bc249360e 100644 --- a/nixos/modules/installer/tools/nixos-install.sh +++ b/nixos/modules/installer/tools/nixos-install.sh @@ -259,9 +259,9 @@ chroot $mountPoint /nix/var/nix/profiles/system/activate # Ask the user to set a root password. -if [ -z "$noRootPasswd" ] && chroot $mountPoint [ -x /run/wrappers/passwd ] && [ -t 0 ]; then +if [ -z "$noRootPasswd" ] && chroot $mountPoint [ -x /run/wrappers/bin/passwd ] && [ -t 0 ]; then echo "setting root password..." - chroot $mountPoint /run/wrappers/passwd + chroot $mountPoint /run/wrappers/bin/passwd fi diff --git a/nixos/modules/security/apparmor-suid.nix b/nixos/modules/security/apparmor-suid.nix index e7b870864ee..dfbf5d859ba 100644 --- a/nixos/modules/security/apparmor-suid.nix +++ b/nixos/modules/security/apparmor-suid.nix @@ -19,7 +19,7 @@ with lib; config = mkIf (cfg.confineSUIDApplications) { security.apparmor.profiles = [ (pkgs.writeText "ping" '' #include - /run/wrappers/ping { + /run/wrappers/bin/ping { #include #include #include @@ -33,7 +33,6 @@ with lib; ${pkgs.attr.out}/lib/libattr.so* mr, ${pkgs.iputils}/bin/ping mixr, - /run/wrappers/ping.real r, #/etc/modules.conf r, diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 0170da03689..8837ac35a53 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -17,7 +17,9 @@ let source=/nix/var/nix/profiles/default/bin/${program} fi - gcc -Wall -O2 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"${config.security.wrapperDir}\" \ + parentWrapperDir=$(dirname ${wrapperDir}) + + gcc -Wall -O2 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"$parentWrapperDir\" \ -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 ''; @@ -155,7 +157,7 @@ in security.wrapperDir = lib.mkOption { type = lib.types.path; - default = "/run/wrappers"; + default = "/run/wrappers/bin"; internal = true; description = '' This option defines the path to the wrapper programs. It @@ -181,11 +183,36 @@ in # programs to be wrapped. WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin + if [ -d ${config.security.old-wrapperDir} ]; then + rm -rf ${config.security.old-wrapperDir} + fi + + parentWrapperDir="$(dirname ${wrapperDir})" + mkdir -p ${wrapperDir} - wrapperDir=$(mktemp --directory --tmpdir=${wrapperDir} wrappers.XXXXXXXXXX) + wrapperDir=$(mktemp --directory --tmpdir="$parentWrapperDir" wrappers.XXXXXXXXXX) chmod a+rx $wrapperDir ${lib.concatStringsSep "\n" mkWrappedPrograms} + + if [ -L ${wrapperDir} ]; then + # Atomically replace the symlink + # See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/ + old=$(readlink ${wrapperDir}) + ln --symbolic --force --no-dereference $wrapperDir ${wrapperDir}-tmp + mv --no-target-directory ${wrapperDir}-tmp ${wrapperDir} + rm --force --recursive $old + elif [ -d ${wrapperDir} ]; then + # Compatibility with old state, just remove the folder and symlink + rm -f ${wrapperDir}/* + # if it happens to be a tmpfs + ${pkgs.utillinux}/bin/umount ${wrapperDir} || true + rm -d ${wrapperDir} + ln -d --symbolic $wrapperDir ${wrapperDir} + else + # For initial setup + ln --symbolic $wrapperDir ${wrapperDir} + fi ''; }; } diff --git a/nixos/modules/services/logging/logcheck.nix b/nixos/modules/services/logging/logcheck.nix index c933c496479..72925b95cae 100644 --- a/nixos/modules/services/logging/logcheck.nix +++ b/nixos/modules/services/logging/logcheck.nix @@ -29,8 +29,8 @@ let }; cronJob = '' - @reboot logcheck env PATH=/run/wrappers:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck -R ${flags} - 2 ${cfg.timeOfDay} * * * logcheck env PATH=/run/wrappers:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck ${flags} + @reboot logcheck env PATH=/run/wrappers/bin:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck -R ${flags} + 2 ${cfg.timeOfDay} * * * logcheck env PATH=/run/wrappers/bin:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck ${flags} ''; writeIgnoreRule = name: {level, regex, ...}: diff --git a/nixos/modules/services/mail/dovecot.nix b/nixos/modules/services/mail/dovecot.nix index 7cea2f75439..3b25e41edb1 100644 --- a/nixos/modules/services/mail/dovecot.nix +++ b/nixos/modules/services/mail/dovecot.nix @@ -13,7 +13,7 @@ let '' base_dir = ${baseDir} protocols = ${concatStringsSep " " cfg.protocols} - sendmail_path = /run/wrappers/sendmail + sendmail_path = /run/wrappers/bin/sendmail '' (if isNull cfg.sslServerCert then '' diff --git a/nixos/modules/services/mail/exim.nix b/nixos/modules/services/mail/exim.nix index 71414bddd5d..b05344fa9b5 100644 --- a/nixos/modules/services/mail/exim.nix +++ b/nixos/modules/services/mail/exim.nix @@ -70,7 +70,7 @@ in etc."exim.conf".text = '' exim_user = ${cfg.user} exim_group = ${cfg.group} - exim_path = /run/wrappers/exim + exim_path = /run/wrappers/bin/exim spool_directory = ${cfg.spoolDir} ${cfg.config} ''; diff --git a/nixos/modules/services/monitoring/munin.nix b/nixos/modules/services/monitoring/munin.nix index cd4a5125029..6d2ce538368 100644 --- a/nixos/modules/services/monitoring/munin.nix +++ b/nixos/modules/services/monitoring/munin.nix @@ -34,7 +34,7 @@ let cap=$(sed -nr 's/.*#%#\s+capabilities\s*=\s*(.+)/\1/p' $file) wrapProgram $file \ - --set PATH "/run/wrappers:/run/current-system/sw/bin:/run/current-system/sw/bin" \ + --set PATH "/run/wrappers/bin:/run/current-system/sw/bin:/run/current-system/sw/bin" \ --set MUNIN_LIBDIR "${pkgs.munin}/lib" \ --set MUNIN_PLUGSTATE "/var/run/munin" @@ -183,7 +183,7 @@ in mkdir -p /etc/munin/plugins rm -rf /etc/munin/plugins/* - PATH="/run/wrappers:/run/current-system/sw/bin:/run/current-system/sw/bin" ${pkgs.munin}/sbin/munin-node-configure --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${muninPlugins} --servicedir=/etc/munin/plugins 2>/dev/null | ${pkgs.bash}/bin/bash + PATH="/run/wrappers/bin:/run/current-system/sw/bin:/run/current-system/sw/bin" ${pkgs.munin}/sbin/munin-node-configure --shell --families contrib,auto,manual --config ${nodeConf} --libdir=${muninPlugins} --servicedir=/etc/munin/plugins 2>/dev/null | ${pkgs.bash}/bin/bash ''; serviceConfig = { ExecStart = "${pkgs.munin}/sbin/munin-node --config ${nodeConf} --servicedir /etc/munin/plugins/"; diff --git a/nixos/modules/services/monitoring/smartd.nix b/nixos/modules/services/monitoring/smartd.nix index af02d73597f..4d10299a987 100644 --- a/nixos/modules/services/monitoring/smartd.nix +++ b/nixos/modules/services/monitoring/smartd.nix @@ -124,7 +124,7 @@ in }; mailer = mkOption { - default = "/run/wrappers/sendmail"; + default = "/run/wrappers/bin/sendmail"; type = types.path; description = '' Sendmail-compatible binary to be used to send the messages. diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix index 8cc8f21851c..09a11585bc9 100644 --- a/nixos/modules/services/network-filesystems/samba.nix +++ b/nixos/modules/services/network-filesystems/samba.nix @@ -30,7 +30,7 @@ let '' [ global ] security = ${cfg.securityType} - passwd program = /run/wrappers/passwd %u + passwd program = /run/wrappers/bin/passwd %u pam password change = ${smbToString cfg.syncPasswordsByPam} invalid users = ${smbToString cfg.invalidUsers} diff --git a/nixos/modules/services/networking/prayer.nix b/nixos/modules/services/networking/prayer.nix index 58e6ad8a683..8cd4a082353 100644 --- a/nixos/modules/services/networking/prayer.nix +++ b/nixos/modules/services/networking/prayer.nix @@ -18,7 +18,7 @@ let var_prefix = "${stateDir}" prayer_user = "${prayerUser}" prayer_group = "${prayerGroup}" - sendmail_path = "/run/wrappers/sendmail" + sendmail_path = "/run/wrappers/bin/sendmail" use_http_port ${cfg.port} diff --git a/nixos/modules/services/networking/smokeping.nix b/nixos/modules/services/networking/smokeping.nix index b7bb55f5508..eedc2759337 100644 --- a/nixos/modules/services/networking/smokeping.nix +++ b/nixos/modules/services/networking/smokeping.nix @@ -226,7 +226,7 @@ in sendmail = mkOption { type = types.nullOr types.path; default = null; - example = "/run/wrappers/sendmail"; + example = "/run/wrappers/bin/sendmail"; description = "Use this sendmail compatible script to deliver alerts"; }; smokeMailTemplate = mkOption { diff --git a/nixos/modules/services/scheduling/atd.nix b/nixos/modules/services/scheduling/atd.nix index 7b4937b5c67..f3ada6b7496 100644 --- a/nixos/modules/services/scheduling/atd.nix +++ b/nixos/modules/services/scheduling/atd.nix @@ -42,13 +42,13 @@ in config = mkIf cfg.enable { - security.wrappers.setuid = map (program: "${program}" = { + security.wrappers = map (program: {"${program}" = { source = "${pkgs.atd}/bin/${program}"; owner = "atd"; group = "atd"; setuid = true; setgid = true; - }) [ "at" "atq" "atrm" "batch" ]; + };}) [ "at" "atq" "atrm" "batch" ]; environment.systemPackages = [ at ]; diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix index 7bd1e481804..48c5f6be316 100644 --- a/nixos/modules/services/scheduling/cron.nix +++ b/nixos/modules/services/scheduling/cron.nix @@ -20,7 +20,7 @@ let cronNixosPkg = pkgs.cron.override { # The mail.nix nixos module, if there is any local mail system enabled, # should have sendmail in this path. - sendmailPath = "/run/wrappers/sendmail"; + sendmailPath = "/run/wrappers/bin/sendmail"; }; allFiles = diff --git a/nixos/modules/services/scheduling/fcron.nix b/nixos/modules/services/scheduling/fcron.nix index f0de996224f..339b0de66e9 100644 --- a/nixos/modules/services/scheduling/fcron.nix +++ b/nixos/modules/services/scheduling/fcron.nix @@ -96,7 +96,7 @@ in fcronallow = /etc/fcron.allow fcrondeny = /etc/fcron.deny shell = /bin/sh - sendmail = /run/wrappers/sendmail + sendmail = /run/wrappers/bin/sendmail editor = /run/current-system/sw/bin/vi ''; target = "fcron.conf"; diff --git a/nixos/modules/system/boot/stage-2-init.sh b/nixos/modules/system/boot/stage-2-init.sh index ffc0700806c..f827e530f87 100644 --- a/nixos/modules/system/boot/stage-2-init.sh +++ b/nixos/modules/system/boot/stage-2-init.sh @@ -131,11 +131,6 @@ if [ -n "@useHostResolvConf@" -a -e /etc/resolv.conf ]; then cat /etc/resolv.conf | resolvconf -m 1000 -a host fi -# Create /run/wrappers as a tmpfs. -rm -rf /run/wrappers -mkdir -m 0755 -p /run/wrappers -mount -t tmpfs -o "mode=0755" tmpfs /run/wrappers - # Log the script output to /dev/kmsg or /run/log/stage-2-init.log. # Only at this point are all the necessary prerequisites ready for these commands. exec {logOutFd}>&1 {logErrFd}>&2 diff --git a/nixos/modules/virtualisation/virtualbox-host.nix b/nixos/modules/virtualisation/virtualbox-host.nix index 70ee44680ab..501ed9bc683 100644 --- a/nixos/modules/virtualisation/virtualbox-host.nix +++ b/nixos/modules/virtualisation/virtualbox-host.nix @@ -69,12 +69,12 @@ in environment.systemPackages = [ virtualbox ]; security.wrappers = let - mkSuid = program: "${program}" = { + mkSuid = program: {"${program}" = { source = "${virtualbox}/libexec/virtualbox/${program}"; owner = "root"; group = "vboxusers"; setuid = true; - }; + };}; in mkIf cfg.enableHardening (map mkSuid [ "VBoxHeadless" "VBoxNetAdpCtl" diff --git a/nixos/tests/smokeping.nix b/nixos/tests/smokeping.nix index 5e2d013abc5..4c77e4b7861 100644 --- a/nixos/tests/smokeping.nix +++ b/nixos/tests/smokeping.nix @@ -14,7 +14,7 @@ import ./make-test.nix ({ pkgs, ...} : { mailHost = "127.0.0.2"; probeConfig = '' + FPing - binary = /run/wrappers/fping + binary = /run/wrappers/bin/fping offset = 0% ''; }; diff --git a/pkgs/applications/editors/sublime3/default.nix b/pkgs/applications/editors/sublime3/default.nix index 1c24ff4737b..f900a4e9147 100644 --- a/pkgs/applications/editors/sublime3/default.nix +++ b/pkgs/applications/editors/sublime3/default.nix @@ -1,5 +1,5 @@ { fetchurl, stdenv, glib, xorg, cairo, gtk2, pango, makeWrapper, openssl, bzip2, - pkexecPath ? "/run/wrappers/pkexec", libredirect, + pkexecPath ? "/run/wrappers/bin/pkexec", libredirect, gksuSupport ? false, gksu}: assert stdenv.system == "i686-linux" || stdenv.system == "x86_64-linux"; diff --git a/pkgs/applications/networking/browsers/chromium/default.nix b/pkgs/applications/networking/browsers/chromium/default.nix index 7009cf17fab..c59d6b00945 100644 --- a/pkgs/applications/networking/browsers/chromium/default.nix +++ b/pkgs/applications/networking/browsers/chromium/default.nix @@ -83,9 +83,9 @@ in stdenv.mkDerivation { ed -v -s "$out/bin/chromium" << EOF 2i - if [ -x "/run/wrappers/${sandboxExecutableName}" ] + if [ -x "/run/wrappers/bin/${sandboxExecutableName}" ] then - export CHROME_DEVEL_SANDBOX="/run/wrappers/${sandboxExecutableName}" + export CHROME_DEVEL_SANDBOX="/run/wrappers/bin/${sandboxExecutableName}" else export CHROME_DEVEL_SANDBOX="$sandbox/bin/${sandboxExecutableName}" fi diff --git a/pkgs/applications/networking/instant-messengers/gale/gale-install.in.patch b/pkgs/applications/networking/instant-messengers/gale/gale-install.in.patch index 4b59f1a376d..33e3e09a96d 100644 --- a/pkgs/applications/networking/instant-messengers/gale/gale-install.in.patch +++ b/pkgs/applications/networking/instant-messengers/gale/gale-install.in.patch @@ -26,7 +26,7 @@ index 50e8ad8..eec0ed2 100644 + is_nixos=no +fi + -+if [ -u /run/wrappers/gksign ]; then ++if [ -u /run/wrappers/bin/gksign ]; then + cat < -#define EXECUTE CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/start_kdeinit" -+#define EXECUTE "/run/wrappers/start_kdeinit" ++#define EXECUTE "/run/wrappers/bin/start_kdeinit" #if KDEINIT_OOM_PROTECT diff --git a/pkgs/development/libraries/libgksu/default.nix b/pkgs/development/libraries/libgksu/default.nix index 6d57ca2397e..e96ef7329a2 100644 --- a/pkgs/development/libraries/libgksu/default.nix +++ b/pkgs/development/libraries/libgksu/default.nix @@ -57,8 +57,8 @@ stdenv.mkDerivation rec { # Fix some binary paths sed -i -e 's|/usr/bin/xauth|${xauth}/bin/xauth|g' libgksu/gksu-run-helper.c libgksu/libgksu.c - sed -i -e 's|/usr/bin/sudo|/run/wrappers/sudo|g' libgksu/libgksu.c - sed -i -e 's|/bin/su\([^d]\)|/run/wrappers/su\1|g' libgksu/libgksu.c + sed -i -e 's|/usr/bin/sudo|/run/wrappers/bin/sudo|g' libgksu/libgksu.c + sed -i -e 's|/bin/su\([^d]\)|/run/wrappers/bin/su\1|g' libgksu/libgksu.c touch NEWS README ''; diff --git a/pkgs/development/libraries/polkit/default.nix b/pkgs/development/libraries/polkit/default.nix index b2e2ecf0493..27482743d2c 100644 --- a/pkgs/development/libraries/polkit/default.nix +++ b/pkgs/development/libraries/polkit/default.nix @@ -5,7 +5,7 @@ let system = "/var/run/current-system/sw"; - setuid = "/run/wrappers"; #TODO: from config.security.wrapperDir; + setuid = "/run/wrappers/bin"; #TODO: from config.security.wrapperDir; foolVars = { SYSCONF = "/etc"; diff --git a/pkgs/development/tools/unity3d/default.nix b/pkgs/development/tools/unity3d/default.nix index 2d4977a3195..73cb902ae69 100644 --- a/pkgs/development/tools/unity3d/default.nix +++ b/pkgs/development/tools/unity3d/default.nix @@ -94,7 +94,7 @@ in stdenv.mkDerivation rec { unitydir="$out/opt/Unity/Editor" mkdir -p $unitydir mv Editor/* $unitydir - ln -sf /run/wrappers/${chromium.sandboxExecutableName} $unitydir/chrome-sandbox + ln -sf /run/wrappers/bin/${chromium.sandboxExecutableName} $unitydir/chrome-sandbox mkdir -p $out/share/applications sed "/^Exec=/c\Exec=$out/bin/unity-editor" \ diff --git a/pkgs/os-specific/linux/fuse/default.nix b/pkgs/os-specific/linux/fuse/default.nix index 29bcc58c7c0..db18b13bfb8 100644 --- a/pkgs/os-specific/linux/fuse/default.nix +++ b/pkgs/os-specific/linux/fuse/default.nix @@ -23,7 +23,7 @@ stdenv.mkDerivation rec { # Ensure that FUSE calls the setuid wrapper, not # $out/bin/fusermount. It falls back to calling fusermount in # $PATH, so it should also work on non-NixOS systems. - export NIX_CFLAGS_COMPILE="-DFUSERMOUNT_DIR=\"/run/wrappers\"" + export NIX_CFLAGS_COMPILE="-DFUSERMOUNT_DIR=\"/run/wrappers/bin\"" sed -e 's@/bin/@${utillinux}/bin/@g' -i lib/mount_util.c sed -e 's@CONFIG_RPATH=/usr/share/gettext/config.rpath@CONFIG_RPATH=${gettext}/share/gettext/config.rpath@' -i makeconf.sh diff --git a/pkgs/os-specific/linux/mdadm/4.nix b/pkgs/os-specific/linux/mdadm/4.nix index af8e53ec3a2..05d98de0b23 100644 --- a/pkgs/os-specific/linux/mdadm/4.nix +++ b/pkgs/os-specific/linux/mdadm/4.nix @@ -31,7 +31,7 @@ stdenv.mkDerivation rec { preConfigure = '' sed -e 's@/lib/udev@''${out}/lib/udev@' \ -e 's@ -Werror @ @' \ - -e 's@/usr/sbin/sendmail@/run/wrappers/sendmail@' -i Makefile + -e 's@/usr/sbin/sendmail@/run/wrappers/bin/sendmail@' -i Makefile ''; meta = { diff --git a/pkgs/os-specific/linux/mdadm/default.nix b/pkgs/os-specific/linux/mdadm/default.nix index d9bdf21723b..e0109791ef2 100644 --- a/pkgs/os-specific/linux/mdadm/default.nix +++ b/pkgs/os-specific/linux/mdadm/default.nix @@ -31,7 +31,7 @@ stdenv.mkDerivation rec { preConfigure = '' sed -e 's@/lib/udev@''${out}/lib/udev@' \ -e 's@ -Werror @ @' \ - -e 's@/usr/sbin/sendmail@/run/wrappers/sendmail@' -i Makefile + -e 's@/usr/sbin/sendmail@/run/wrappers/bin/sendmail@' -i Makefile ''; meta = { diff --git a/pkgs/os-specific/linux/pam/default.nix b/pkgs/os-specific/linux/pam/default.nix index dc61b3f27f6..5189b84ff7e 100644 --- a/pkgs/os-specific/linux/pam/default.nix +++ b/pkgs/os-specific/linux/pam/default.nix @@ -34,7 +34,7 @@ stdenv.mkDerivation rec { postInstall = '' mv -v $out/sbin/unix_chkpwd{,.orig} - ln -sv /run/wrappers/unix_chkpwd $out/sbin/unix_chkpwd + ln -sv /run/wrappers/bin/unix_chkpwd $out/sbin/unix_chkpwd ''; /* rm -rf $out/etc mkdir -p $modules/lib diff --git a/pkgs/os-specific/linux/util-linux/default.nix b/pkgs/os-specific/linux/util-linux/default.nix index 90fbf861448..6c3aacbef29 100644 --- a/pkgs/os-specific/linux/util-linux/default.nix +++ b/pkgs/os-specific/linux/util-linux/default.nix @@ -36,7 +36,7 @@ stdenv.mkDerivation rec { --enable-last --enable-mesg --disable-use-tty-group - --enable-fs-paths-default=/run/wrappers:/var/run/current-system/sw/bin:/sbin + --enable-fs-paths-default=/run/wrappers/bin:/var/run/current-system/sw/bin:/sbin ${if ncurses == null then "--without-ncurses" else ""} ${if systemd == null then "" else '' --with-systemd diff --git a/pkgs/servers/interlock/default.nix b/pkgs/servers/interlock/default.nix index b58c1b50e03..a0b59d332a3 100644 --- a/pkgs/servers/interlock/default.nix +++ b/pkgs/servers/interlock/default.nix @@ -30,7 +30,7 @@ buildGoPackage rec { -e 's|/bin/chown|${coreutils}/bin/chown|' \ -e 's|/bin/date|${coreutils}/bin/date|' \ -e 's|/sbin/poweroff|${systemd}/sbin/poweroff|' \ - -e 's|/usr/bin/sudo|/run/wrappers/sudo|' \ + -e 's|/usr/bin/sudo|/run/wrappers/bin/sudo|' \ -e 's|/sbin/cryptsetup|${cryptsetup}/bin/cryptsetup|' ''; } diff --git a/pkgs/servers/mail/petidomo/default.nix b/pkgs/servers/mail/petidomo/default.nix index 1770517047f..395f3ded7fd 100644 --- a/pkgs/servers/mail/petidomo/default.nix +++ b/pkgs/servers/mail/petidomo/default.nix @@ -1,4 +1,4 @@ -{ stdenv, fetchurl, flex, bison, sendmailPath ? "/run/wrappers/sendmail" }: +{ stdenv, fetchurl, flex, bison, sendmailPath ? "/run/wrappers/bin/sendmail" }: stdenv.mkDerivation rec { name = "petidomo-4.3"; diff --git a/pkgs/servers/monitoring/nagios/plugins/official-2.x.nix b/pkgs/servers/monitoring/nagios/plugins/official-2.x.nix index 30bd7e8a7c3..1ea6f88084d 100644 --- a/pkgs/servers/monitoring/nagios/plugins/official-2.x.nix +++ b/pkgs/servers/monitoring/nagios/plugins/official-2.x.nix @@ -16,8 +16,8 @@ stdenv.mkDerivation rec { # configured on the build machine). preConfigure= " configureFlagsArray=( - --with-ping-command='/run/wrappers/ping -n -U -w %d -c %d %s' - --with-ping6-command='/run/wrappers/ping6 -n -U -w %d -c %d %s' + --with-ping-command='/run/wrappers/bin/ping -n -U -w %d -c %d %s' + --with-ping6-command='/run/wrappers/bin/ping6 -n -U -w %d -c %d %s' ) "; diff --git a/pkgs/tools/X11/x11vnc/default.nix b/pkgs/tools/X11/x11vnc/default.nix index b343a7da378..2d319cccf20 100644 --- a/pkgs/tools/X11/x11vnc/default.nix +++ b/pkgs/tools/X11/x11vnc/default.nix @@ -20,10 +20,10 @@ stdenv.mkDerivation rec { configureFlags="--mandir=$out/share/man" substituteInPlace x11vnc/unixpw.c \ - --replace '"/bin/su"' '"/run/wrappers/su"' \ + --replace '"/bin/su"' '"/run/wrappers/bin/su"' \ --replace '"/bin/true"' '"${coreutils}/bin/true"' - sed -i -e '/#!\/bin\/sh/a"PATH=${xorg.xdpyinfo}\/bin:${xorg.xauth}\/bin:$PATH\\n"' -e 's|/bin/su|/run/wrappers/su|g' x11vnc/ssltools.h + sed -i -e '/#!\/bin\/sh/a"PATH=${xorg.xdpyinfo}\/bin:${xorg.xauth}\/bin:$PATH\\n"' -e 's|/bin/su|/run/wrappers/bin/su|g' x11vnc/ssltools.h ''; meta = { diff --git a/pkgs/tools/admin/certbot/default.nix b/pkgs/tools/admin/certbot/default.nix index 366213d2e1e..3648cb2c136 100644 --- a/pkgs/tools/admin/certbot/default.nix +++ b/pkgs/tools/admin/certbot/default.nix @@ -31,7 +31,7 @@ python2Packages.buildPythonApplication rec { buildInputs = [ dialog ] ++ (with python2Packages; [ nose mock gnureadline ]); patchPhase = '' - substituteInPlace certbot/notify.py --replace "/usr/sbin/sendmail" "/run/wrappers/sendmail" + substituteInPlace certbot/notify.py --replace "/usr/sbin/sendmail" "/run/wrappers/bin/sendmail" substituteInPlace certbot/util.py --replace "sw_vers" "/usr/bin/sw_vers" ''; diff --git a/pkgs/tools/misc/debian-devscripts/default.nix b/pkgs/tools/misc/debian-devscripts/default.nix index be3b674de04..cbc7a2e7e46 100644 --- a/pkgs/tools/misc/debian-devscripts/default.nix +++ b/pkgs/tools/misc/debian-devscripts/default.nix @@ -2,7 +2,7 @@ , FileDesktopEntry, libxslt, docbook_xsl, makeWrapper , python3Packages , perlPackages, curl, gnupg, diffutils -, sendmailPath ? "/run/wrappers/sendmail" +, sendmailPath ? "/run/wrappers/bin/sendmail" }: let diff --git a/pkgs/tools/security/ecryptfs/default.nix b/pkgs/tools/security/ecryptfs/default.nix index 98e06d1de3e..ab4867a4cc8 100644 --- a/pkgs/tools/security/ecryptfs/default.nix +++ b/pkgs/tools/security/ecryptfs/default.nix @@ -11,7 +11,7 @@ stdenv.mkDerivation rec { }; # TODO: replace wrapperDir below with from config.security.wrapperDir; - wrapperDir = "/run/wrappers"; + wrapperDir = "/run/wrappers/bin"; postPatch = '' FILES="$(grep -r '/bin/sh' src/utils -l; find src -name \*.c)" diff --git a/pkgs/tools/security/ecryptfs/helper.nix b/pkgs/tools/security/ecryptfs/helper.nix index 3daaadcaad6..05327ad3a09 100644 --- a/pkgs/tools/security/ecryptfs/helper.nix +++ b/pkgs/tools/security/ecryptfs/helper.nix @@ -18,7 +18,7 @@ stdenv.mkDerivation rec { buildInputs = [ makeWrapper ]; - # Do not hardcode PATH to ${ecryptfs} as we need the script to invoke executables from /run/wrappers + # Do not hardcode PATH to ${ecryptfs} as we need the script to invoke executables from /run/wrappers/bin installPhase = '' mkdir -p $out/bin $out/libexec cp $src $out/libexec/ecryptfs-helper.py diff --git a/pkgs/tools/security/sudo/default.nix b/pkgs/tools/security/sudo/default.nix index 0d2953c6f45..9f56a9d7f26 100644 --- a/pkgs/tools/security/sudo/default.nix +++ b/pkgs/tools/security/sudo/default.nix @@ -1,5 +1,5 @@ { stdenv, fetchurl, coreutils, pam, groff -, sendmailPath ? "/run/wrappers/sendmail" +, sendmailPath ? "/run/wrappers/bin/sendmail" , withInsults ? false }: diff --git a/pkgs/tools/system/at/default.nix b/pkgs/tools/system/at/default.nix index 9f8bad00ca4..185645763fd 100644 --- a/pkgs/tools/system/at/default.nix +++ b/pkgs/tools/system/at/default.nix @@ -1,4 +1,4 @@ -{ fetchurl, stdenv, bison, flex, pam, sendmailPath ? "/run/wrappers/sendmail" }: +{ fetchurl, stdenv, bison, flex, pam, sendmailPath ? "/run/wrappers/bin/sendmail" }: stdenv.mkDerivation { name = "at-3.1.16"; diff --git a/pkgs/tools/system/cron/default.nix b/pkgs/tools/system/cron/default.nix index 8a6a5dc15d3..dec1bacd741 100644 --- a/pkgs/tools/system/cron/default.nix +++ b/pkgs/tools/system/cron/default.nix @@ -23,7 +23,7 @@ stdenv.mkDerivation { #define _PATH_SENDMAIL "${sendmailPath}" #undef _PATH_DEFPATH - #define _PATH_DEFPATH "/run/wrappers:/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/run/current-system/sw/bin:/run/current-system/sw/sbin:/usr/bin:/bin" + #define _PATH_DEFPATH "/run/wrappers/bin:/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/run/current-system/sw/bin:/run/current-system/sw/sbin:/usr/bin:/bin" __EOT__ # Implicit saved uids do not work here due to way NixOS uses setuid wrappers diff --git a/pkgs/tools/system/ts/default.nix b/pkgs/tools/system/ts/default.nix index 1dfb856d4d6..97b35378673 100644 --- a/pkgs/tools/system/ts/default.nix +++ b/pkgs/tools/system/ts/default.nix @@ -1,5 +1,5 @@ {stdenv, fetchurl, -sendmailPath ? "/run/wrappers/sendmail" }: +sendmailPath ? "/run/wrappers/bin/sendmail" }: stdenv.mkDerivation rec { From 70b8167d4ac3572a2f364bba18432ea15df92971 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 05:05:30 -0600 Subject: [PATCH 50/74] A few more tweaks --- nixos/modules/security/wrappers/default.nix | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 8837ac35a53..8e20d773125 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -11,7 +11,7 @@ let wrappers); mkWrapper = { program, source ? null, ...}: '' - if ! source=${if source != null then source else "$(readlink -f $(PATH=$WRAPPER_PATH type -tP ${program}))"}; then + if ! source=${if source != null || source != "" then source else "$(readlink -f $(PATH=$WRAPPER_PATH type -tP ${program}))"}; then # If we can't find the program, fall back to the # system profile. source=/nix/var/nix/profiles/default/bin/${program} @@ -183,13 +183,16 @@ in # programs to be wrapped. WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin + # Remove the old /var/setuid-wrappers path from the system... if [ -d ${config.security.old-wrapperDir} ]; then rm -rf ${config.security.old-wrapperDir} fi + # Get the "/run/wrappers" path, we want to place the tmpdirs + # for the wrappers there parentWrapperDir="$(dirname ${wrapperDir})" - mkdir -p ${wrapperDir} + mkdir -p "$parentWrapperDir" wrapperDir=$(mktemp --directory --tmpdir="$parentWrapperDir" wrappers.XXXXXXXXXX) chmod a+rx $wrapperDir @@ -198,7 +201,7 @@ in if [ -L ${wrapperDir} ]; then # Atomically replace the symlink # See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/ - old=$(readlink ${wrapperDir}) + old=$(readlink -f ${wrapperDir}) ln --symbolic --force --no-dereference $wrapperDir ${wrapperDir}-tmp mv --no-target-directory ${wrapperDir}-tmp ${wrapperDir} rm --force --recursive $old From 628e6a83d0f3b7ddc0592c88fef7978a7ee0063e Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 05:33:56 -0600 Subject: [PATCH 51/74] More derp --- .../security/chromium-suid-sandbox.nix | 2 +- nixos/modules/security/duosec.nix | 2 +- nixos/modules/security/pam.nix | 15 ++++++++---- nixos/modules/security/pam_usb.nix | 5 +++- nixos/modules/security/polkit.nix | 6 +++-- nixos/modules/security/sudo.nix | 5 +++- nixos/modules/security/wrappers/default.nix | 24 +------------------ nixos/modules/services/mail/exim.nix | 2 +- .../modules/services/networking/smokeping.nix | 5 +++- nixos/modules/services/scheduling/cron.nix | 2 +- nixos/modules/services/scheduling/fcron.nix | 2 +- .../x11/desktop-managers/enlightenment.nix | 3 ++- nixos/modules/tasks/network-interfaces.nix | 7 +++--- 13 files changed, 38 insertions(+), 42 deletions(-) diff --git a/nixos/modules/security/chromium-suid-sandbox.nix b/nixos/modules/security/chromium-suid-sandbox.nix index 0699fbb728a..0458ffb6c46 100644 --- a/nixos/modules/security/chromium-suid-sandbox.nix +++ b/nixos/modules/security/chromium-suid-sandbox.nix @@ -27,6 +27,6 @@ in config = mkIf cfg.enable { environment.systemPackages = [ sandbox ]; - security.setuidPrograms = [ sandbox.passthru.sandboxExecutableName ]; + security.wrappers."${sandbox.passthru.sandboxExecutableName}".source = "${sandbox}/bin/${sandbox.passthru.sandboxExecutableName}"; }; } diff --git a/nixos/modules/security/duosec.nix b/nixos/modules/security/duosec.nix index ee62c34438e..9ca818e86ff 100644 --- a/nixos/modules/security/duosec.nix +++ b/nixos/modules/security/duosec.nix @@ -188,7 +188,7 @@ in environment.systemPackages = [ pkgs.duo-unix ]; - security.setuidPrograms = [ "login_duo" ]; + security.wrappers.login_duo.source = "${pkgs.duo-unix.out}/bin/login_duo"; environment.etc = loginCfgFile ++ pamCfgFile; /* If PAM *and* SSH are enabled, then don't do anything special. diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index 3c944acf6cf..86143dd2ee5 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -472,13 +472,18 @@ in ++ optionals config.security.pam.enableU2F [ pkgs.pam_u2f ] ++ optionals config.security.pam.enableEcryptfs [ pkgs.ecryptfs ]; - security.setuidPrograms = + security.wrapperssetuidPrograms = optionals config.security.pam.enableEcryptfs [ "mount.ecryptfs_private" "umount.ecryptfs_private" ]; - security.wrappers.unix_chkpwd = { - source = "${pkgs.pam}/sbin/unix_chkpwd.orig"; - owner = "root"; - setuid = true; + security.wrappers = { + unix_chkpwd = { + source = "${pkgs.pam}/sbin/unix_chkpwd.orig"; + owner = "root"; + setuid = true; + }; + } // (mkIf config.security.pam.enableEcryptfs { + "mount.ecryptfs_private".source = "${pkgs.ecryptfs.out}/bin/mount.ecryptfs_private"; + "umount.ecryptfs_private".source = "${pkgs.ecryptfs.out}/bin/umount.ecryptfs_private"; }; environment.etc = diff --git a/nixos/modules/security/pam_usb.nix b/nixos/modules/security/pam_usb.nix index 032f8e38d11..6f811dab8d7 100644 --- a/nixos/modules/security/pam_usb.nix +++ b/nixos/modules/security/pam_usb.nix @@ -33,7 +33,10 @@ in config = mkIf (cfg.enable || anyUsbAuth) { # Make sure pmount and pumount are setuid wrapped. - security.setuidPrograms = [ "pmount" "pumount" ]; + security.wrappers = { + pmount.source = "${pkgs.pmount.out}/bin/pmount"; + pumount.source = "${pkgs.pmount.out}/bin/pumount"; + }; environment.systemPackages = [ pkgs.pmount ]; diff --git a/nixos/modules/security/polkit.nix b/nixos/modules/security/polkit.nix index 547b40cedfd..419abb8b086 100644 --- a/nixos/modules/security/polkit.nix +++ b/nixos/modules/security/polkit.nix @@ -83,8 +83,10 @@ in security.pam.services.polkit-1 = {}; - security.setuidPrograms = [ "pkexec" ]; - security.wrappers."polkit-agent-helper-1".source = "${pkgs.polkit.out}/lib/polkit-1/polkit-agent-helper-1"; + security.wrappers = { + pkexec.source = "${pkgs.polkit.out}/bin/pkexec"; + "polkit-agent-helper-1".source = "${pkgs.polkit.out}/lib/polkit-1/polkit-agent-helper-1"; + }; system.activationScripts.polkit = '' diff --git a/nixos/modules/security/sudo.nix b/nixos/modules/security/sudo.nix index f5612e1b0c5..67a9b9a45ee 100644 --- a/nixos/modules/security/sudo.nix +++ b/nixos/modules/security/sudo.nix @@ -81,7 +81,10 @@ in ${cfg.extraConfig} ''; - security.setuidPrograms = [ "sudo" "sudoedit" ]; + security.wrappers = { + sudo.source = "${pkgs.sudo.out}/bin/sudo"; + sudoedit.source = "${pkgs.sudo.out}/bin/sudoedit"; + }; environment.systemPackages = [ sudo ]; diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 8e20d773125..9909c640647 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -4,22 +4,13 @@ let inherit (config.security) wrapperDir wrappers setuidPrograms; programs = - (map (x: { program = x; owner = "root"; group = "root"; setuid = true; }) setuidPrograms) - ++ (lib.mapAttrsToList (n: v: (if v ? "program" then v else v // {program=n;})) wrappers); mkWrapper = { program, source ? null, ...}: '' - if ! source=${if source != null || source != "" then source else "$(readlink -f $(PATH=$WRAPPER_PATH type -tP ${program}))"}; then - # If we can't find the program, fall back to the - # system profile. - source=/nix/var/nix/profiles/default/bin/${program} - fi - parentWrapperDir=$(dirname ${wrapperDir}) - - gcc -Wall -O2 -DSOURCE_PROG=\"$source\" -DWRAPPER_DIR=\"$parentWrapperDir\" \ + gcc -Wall -O2 -DSOURCE_PROG=\"${source}\" -DWRAPPER_DIR=\"$parentWrapperDir\" \ -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 ''; @@ -96,19 +87,6 @@ in ###### interface options = { - security.setuidPrograms = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = []; - example = ["passwd"]; - description = '' - The Nix store cannot contain setuid/setgid programs directly. - For this reason, NixOS can automatically generate wrapper - programs that have the necessary privileges. This option - lists the names of programs in the system environment for - which setuid root wrappers should be created. - ''; - }; - security.wrappers = lib.mkOption { type = lib.types.attrs; default = {}; diff --git a/nixos/modules/services/mail/exim.nix b/nixos/modules/services/mail/exim.nix index b05344fa9b5..440eae281f4 100644 --- a/nixos/modules/services/mail/exim.nix +++ b/nixos/modules/services/mail/exim.nix @@ -89,7 +89,7 @@ in gid = config.ids.gids.exim; }; - security.setuidPrograms = [ "exim" ]; + security.wrappers.exim.source = "${exim}/bin/exim"; systemd.services.exim = { description = "Exim Mail Daemon"; diff --git a/nixos/modules/services/networking/smokeping.nix b/nixos/modules/services/networking/smokeping.nix index eedc2759337..bac79474527 100644 --- a/nixos/modules/services/networking/smokeping.nix +++ b/nixos/modules/services/networking/smokeping.nix @@ -273,7 +273,10 @@ in message = "services.smokeping: sendmail and Mailhost cannot both be enabled."; } ]; - security.setuidPrograms = [ "fping" "fping6" ]; + security.wrappers = { + fping.source = "${pkgs.fping}/bin/fping"; + "fping6".source = "${pkgs.fping}/bin/fping6"; + }; environment.systemPackages = [ pkgs.fping ]; users.extraUsers = singleton { name = cfg.user; diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix index 48c5f6be316..cc6eb96bf5d 100644 --- a/nixos/modules/services/scheduling/cron.nix +++ b/nixos/modules/services/scheduling/cron.nix @@ -93,7 +93,7 @@ in { services.cron.enable = mkDefault (allFiles != []); } (mkIf (config.services.cron.enable) { - security.setuidPrograms = [ "crontab" ]; + security.wrappers.crontab.source = "${pkgs.cronNixosPkg.out}/bin/crontab"; environment.systemPackages = [ cronNixosPkg ]; environment.etc.crontab = { source = pkgs.runCommand "crontabs" { inherit allFiles; preferLocalBuild = true; } diff --git a/nixos/modules/services/scheduling/fcron.nix b/nixos/modules/services/scheduling/fcron.nix index 339b0de66e9..e4ada276871 100644 --- a/nixos/modules/services/scheduling/fcron.nix +++ b/nixos/modules/services/scheduling/fcron.nix @@ -106,7 +106,7 @@ in environment.systemPackages = [ pkgs.fcron ]; - security.setuidPrograms = [ "fcrontab" ]; + security.wrappers.fcrontab.source = "${pkgs.fcron.out}/bin/fcrontab"; systemd.services.fcron = { description = "fcron daemon"; after = [ "local-fs.target" ]; diff --git a/nixos/modules/services/x11/desktop-managers/enlightenment.nix b/nixos/modules/services/x11/desktop-managers/enlightenment.nix index feee6ba87ec..77050bcb23f 100644 --- a/nixos/modules/services/x11/desktop-managers/enlightenment.nix +++ b/nixos/modules/services/x11/desktop-managers/enlightenment.nix @@ -62,7 +62,8 @@ in ''; }]; - security.setuidPrograms = [ "e_freqset" ]; + security.wrappers.e_freqset.source = "${e.enlightenment.out}/bin/e_freqset"; + environment.etc = singleton { source = "${pkgs.xkeyboard_config}/etc/X11/xkb"; target = "X11/xkb"; diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 1afcddd915f..a01bf21af51 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -912,9 +912,10 @@ in # If the linux kernel IS older than 4.3, create setuid wrappers # for ping and ping6 - security.setuidPrograms = mkIf (versionOlder (getVersion config.boot.kernelPackages.kernel) "4.3") [ - "ping" "ping6" - ]; + security.wrappers = mkIf (versionOlder (getVersion config.boot.kernelPackages.kernel) "4.3") { + ping.source = "${pkgs.iputils.out}/bin/ping"; + "ping6".source = "${pkgs.iputils.out}/bin/ping6"; + }; # Set the host and domain names in the activation script. Don't # clear it if it's not configured in the NixOS configuration, From 1cc500ea8e66b2f09735e7dccc756ba00518bd8a Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 05:34:50 -0600 Subject: [PATCH 52/74] Syntax wibble --- nixos/modules/security/pam.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index 86143dd2ee5..713e15322c7 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -484,7 +484,7 @@ in } // (mkIf config.security.pam.enableEcryptfs { "mount.ecryptfs_private".source = "${pkgs.ecryptfs.out}/bin/mount.ecryptfs_private"; "umount.ecryptfs_private".source = "${pkgs.ecryptfs.out}/bin/umount.ecryptfs_private"; - }; + }); environment.etc = mapAttrsToList (n: v: makePAMService v) config.security.pam.services; From a3e9d77640b686c29692294ca7d557b11dfe2c65 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 05:36:47 -0600 Subject: [PATCH 53/74] More derp? It's 5am... --- nixos/modules/tasks/network-interfaces.nix | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index a01bf21af51..3ef0a2ee1a2 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -898,23 +898,27 @@ in # Capabilities won't work unless we have at-least a 4.3 Linux # kernel because we need the ambient capability - security.wrappers = mkIf (versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.3") { - ping = { - source = "${pkgs.iputils.out}/bin/ping"; - capabilities = "cap_net_raw+p"; - }; + security = mkIf (versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.3") { + wrappers = { + ping = { + source = "${pkgs.iputils.out}/bin/ping"; + capabilities = "cap_net_raw+p"; + }; - ping6 = { - source = "${pkgs.iputils.out}/bin/ping6"; - capabilities = "cap_net_raw+p"; + ping6 = { + source = "${pkgs.iputils.out}/bin/ping6"; + capabilities = "cap_net_raw+p"; + }; }; }; # If the linux kernel IS older than 4.3, create setuid wrappers # for ping and ping6 - security.wrappers = mkIf (versionOlder (getVersion config.boot.kernelPackages.kernel) "4.3") { - ping.source = "${pkgs.iputils.out}/bin/ping"; - "ping6".source = "${pkgs.iputils.out}/bin/ping6"; + security = mkIf (versionOlder (getVersion config.boot.kernelPackages.kernel) "4.3") { + wrappers = { + ping.source = "${pkgs.iputils.out}/bin/ping"; + "ping6".source = "${pkgs.iputils.out}/bin/ping6"; + }; }; # Set the host and domain names in the activation script. Don't From 3215bcf4450080c44411171b4d69d0cb2dd1b1bd Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 05:39:18 -0600 Subject: [PATCH 54/74] Beebooboop --- nixos/modules/tasks/network-interfaces.nix | 28 ++++++++-------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 3ef0a2ee1a2..dc77a6a40f8 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -898,27 +898,19 @@ in # Capabilities won't work unless we have at-least a 4.3 Linux # kernel because we need the ambient capability - security = mkIf (versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.3") { - wrappers = { - ping = { - source = "${pkgs.iputils.out}/bin/ping"; - capabilities = "cap_net_raw+p"; - }; - - ping6 = { - source = "${pkgs.iputils.out}/bin/ping6"; - capabilities = "cap_net_raw+p"; - }; + security.wrappers = if (versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.3") then { + ping = { + source = "${pkgs.iputils.out}/bin/ping"; + capabilities = "cap_net_raw+p"; }; - }; - # If the linux kernel IS older than 4.3, create setuid wrappers - # for ping and ping6 - security = mkIf (versionOlder (getVersion config.boot.kernelPackages.kernel) "4.3") { - wrappers = { - ping.source = "${pkgs.iputils.out}/bin/ping"; - "ping6".source = "${pkgs.iputils.out}/bin/ping6"; + ping6 = { + source = "${pkgs.iputils.out}/bin/ping6"; + capabilities = "cap_net_raw+p"; }; + } else { + ping.source = "${pkgs.iputils.out}/bin/ping"; + "ping6".source = "${pkgs.iputils.out}/bin/ping6"; }; # Set the host and domain names in the activation script. Don't From cfe4351c33bd23e7007179d6c75299919a873210 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 05:39:54 -0600 Subject: [PATCH 55/74] I'm clearly very tired --- nixos/modules/security/pam.nix | 3 --- 1 file changed, 3 deletions(-) diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index 713e15322c7..711e4c55c7d 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -472,9 +472,6 @@ in ++ optionals config.security.pam.enableU2F [ pkgs.pam_u2f ] ++ optionals config.security.pam.enableEcryptfs [ pkgs.ecryptfs ]; - security.wrapperssetuidPrograms = - optionals config.security.pam.enableEcryptfs [ "mount.ecryptfs_private" "umount.ecryptfs_private" ]; - security.wrappers = { unix_chkpwd = { source = "${pkgs.pam}/sbin/unix_chkpwd.orig"; From 9f82c9903d8cba0685795c526fe5e7c51a6bc9c8 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 05:44:29 -0600 Subject: [PATCH 56/74] More fixes --- nixos/modules/programs/shadow.nix | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/nixos/modules/programs/shadow.nix b/nixos/modules/programs/shadow.nix index c5a50318026..d497b662113 100644 --- a/nixos/modules/programs/shadow.nix +++ b/nixos/modules/programs/shadow.nix @@ -101,9 +101,15 @@ in chpasswd = { rootOK = true; }; }; - security.setuidPrograms = [ - "su" "chfn" "newuidmap" "newgidmap" - ] ++ lib.optionals config.users.mutableUsers - [ "passwd" "sg" "newgrp" ]; + security.wrappers = { + su.source = "${pkgs.shadow.su}/bin/su"; + chfn.source = "${pkgs.shadow.out}/bin/chfn"; + newuidmap.source = "${pkgs.shadow.out}/bin/newuidmap"; + newgidmap.source = "${pkgs.shadow.out}/bin/newgidmap"; + } // (lib.mkIf config.users.mutableUsers { + passwd.source = "${pkgs.shadow.out}/bin/passwd"; + sg.source = "${pkgs.shadow.out}/bin/sg"; + newgrp.source = "${pkgs.shadow.out}/bin/newgrp"; + }); }; } From c5f1f9a3b5bcf5d2990aba0ab086767d1d384922 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 05:45:43 -0600 Subject: [PATCH 57/74] More mistake fixes --- nixos/modules/programs/kbdlight.nix | 2 +- nixos/modules/programs/light.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nixos/modules/programs/kbdlight.nix b/nixos/modules/programs/kbdlight.nix index 0172368e968..58e45872fac 100644 --- a/nixos/modules/programs/kbdlight.nix +++ b/nixos/modules/programs/kbdlight.nix @@ -11,6 +11,6 @@ in config = mkIf cfg.enable { environment.systemPackages = [ pkgs.kbdlight ]; - security.setuidPrograms = [ "kbdlight" ]; + security.wrappers.kbdlight.source = "${pkgs.kbdlight.out}/bin/kbdlight"; }; } diff --git a/nixos/modules/programs/light.nix b/nixos/modules/programs/light.nix index 09cd1113d9c..6f8c389acc9 100644 --- a/nixos/modules/programs/light.nix +++ b/nixos/modules/programs/light.nix @@ -21,6 +21,6 @@ in config = mkIf cfg.enable { environment.systemPackages = [ pkgs.light ]; - security.setuidPrograms = [ "light" ]; + security.wrappers.light.source = "${pkgs.light.out}/bin/light"; }; } From 9abe7528e4c495c868fa518af50c3cdfd1e755ed Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 11:27:08 -0600 Subject: [PATCH 58/74] Switching locate over to new wrapper API --- nixos/modules/misc/locate.nix | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/nixos/modules/misc/locate.nix b/nixos/modules/misc/locate.nix index a9c84f6db24..089f354f611 100644 --- a/nixos/modules/misc/locate.nix +++ b/nixos/modules/misc/locate.nix @@ -103,15 +103,16 @@ in { config = mkIf cfg.enable { users.extraGroups = mkIf isMLocate { mlocate = {}; }; - security.setuidOwners = mkIf isMLocate - [ { group = "mlocate"; - owner = "root"; - permissions = "u+rx,g+x,o+x"; - setgid = true; - setuid = false; - program = "locate"; - } - ]; + security.wrappers = mkIf isMLocate { + mlocate = { + group = "mlocate"; + owner = "root"; + permissions = "u+rx,g+x,o+x"; + setgid = true; + setuid = false; + program = "locate"; + }; + }; nixpkgs.config = { locate.dbfile = cfg.output; }; From 4856b42ab69beb882414664551f1ca879d379936 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 16:47:14 -0600 Subject: [PATCH 59/74] Gotta provide sane defaults! This is what I get for 5AM coding --- nixos/modules/security/wrappers/default.nix | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 9909c640647..cb288fc0880 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -79,7 +79,13 @@ let (s ? "setguid" && s.setguid == true) || (s ? "permissions") then mkSetuidProgram s - else "" + else mkSetuidProgram + ({ owner = "root"; + group = "root"; + setuid = true; + setgid = false; + permissions = "u+rx,g+x,o+x"; + } // s) ) programs; in { From 0f728de67eeb8b1ebfb0c77418f95f2806f918b5 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 16:52:23 -0600 Subject: [PATCH 60/74] More migration cleanup + todos for cleanup --- nixos/modules/security/wrappers/default.nix | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index cb288fc0880..5ec1a7e6206 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -168,10 +168,24 @@ in WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin # Remove the old /var/setuid-wrappers path from the system... + # + # TDOO: this is only necessary for ugprades 16.09 => 17.x; + # this conditional removal block needs to be removed after + # the release. if [ -d ${config.security.old-wrapperDir} ]; then rm -rf ${config.security.old-wrapperDir} fi + # Remove the old /run/setuid-wrappers-dir path from the + # system as well... + # + # TDOO: this is only necessary for ugprades 16.09 => 17.x; + # this conditional removal block needs to be removed after + # the release. + if [ -d /run/setuid-wrappers-dir ]; then + rm -rf /run/setuid-wrappers-dir + fi + # Get the "/run/wrappers" path, we want to place the tmpdirs # for the wrappers there parentWrapperDir="$(dirname ${wrapperDir})" From f2f3f1479e18b530b57628c7d7725283afb57ac4 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 16:54:27 -0600 Subject: [PATCH 61/74] Derp, wrong path name --- nixos/modules/security/wrappers/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 5ec1a7e6206..73b4cad8687 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -182,8 +182,8 @@ in # TDOO: this is only necessary for ugprades 16.09 => 17.x; # this conditional removal block needs to be removed after # the release. - if [ -d /run/setuid-wrappers-dir ]; then - rm -rf /run/setuid-wrappers-dir + if [ -d /run/setuid-wrapper-dirs ]; then + rm -rf /run/setuid-wrapper-dirs fi # Get the "/run/wrappers" path, we want to place the tmpdirs From 264db4e30936cbb4dd9f88123aafb42a5259e74f Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Sun, 29 Jan 2017 17:10:32 -0600 Subject: [PATCH 62/74] Set merge + mkIf always surprises me --- nixos/modules/programs/shadow.nix | 4 ++-- nixos/modules/security/pam.nix | 4 ++-- nixos/modules/security/wrappers/default.nix | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/nixos/modules/programs/shadow.nix b/nixos/modules/programs/shadow.nix index d497b662113..0f3f42901ba 100644 --- a/nixos/modules/programs/shadow.nix +++ b/nixos/modules/programs/shadow.nix @@ -106,10 +106,10 @@ in chfn.source = "${pkgs.shadow.out}/bin/chfn"; newuidmap.source = "${pkgs.shadow.out}/bin/newuidmap"; newgidmap.source = "${pkgs.shadow.out}/bin/newgidmap"; - } // (lib.mkIf config.users.mutableUsers { + } // (if config.users.mutableUsers then { passwd.source = "${pkgs.shadow.out}/bin/passwd"; sg.source = "${pkgs.shadow.out}/bin/sg"; newgrp.source = "${pkgs.shadow.out}/bin/newgrp"; - }); + } else {}); }; } diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index 711e4c55c7d..3cc5db2fb9b 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -478,10 +478,10 @@ in owner = "root"; setuid = true; }; - } // (mkIf config.security.pam.enableEcryptfs { + } // (if config.security.pam.enableEcryptfs then { "mount.ecryptfs_private".source = "${pkgs.ecryptfs.out}/bin/mount.ecryptfs_private"; "umount.ecryptfs_private".source = "${pkgs.ecryptfs.out}/bin/umount.ecryptfs_private"; - }); + } else {}); environment.etc = mapAttrsToList (n: v: makePAMService v) config.security.pam.services; diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 73b4cad8687..71799175011 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -152,6 +152,9 @@ in ###### implementation config = { + + security.wrappers.fusermount.source = "${pkgs.fuse}/bin/fusermount"; + # Make sure our wrapperDir exports to the PATH env variable when # initializing the shell environment.extraInit = '' From d8ecd5eb0d30c3dc302e336755a4a1d6d0cb1ba4 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Mon, 30 Jan 2017 12:26:56 -0600 Subject: [PATCH 63/74] Switching to individually generated derivations --- nixos/modules/security/wrappers/default.nix | 46 ++++++++++++--------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 71799175011..757765ed08c 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -8,21 +8,24 @@ let (n: v: (if v ? "program" then v else v // {program=n;})) wrappers); - mkWrapper = { program, source ? null, ...}: '' - parentWrapperDir=$(dirname ${wrapperDir}) - gcc -Wall -O2 -DSOURCE_PROG=\"${source}\" -DWRAPPER_DIR=\"$parentWrapperDir\" \ - -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 - ''; - - wrappedPrograms = pkgs.stdenv.mkDerivation { - name = "permissions-wrapper"; - unpackPhase = "true"; - installPhase = '' - mkdir -p $out/bin - ${lib.concatMapStrings mkWrapper programs} - ''; - }; + 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} + ''; + }; ###### Activation script for the setcap wrappers mkSetcapProgram = @@ -32,10 +35,11 @@ let , owner ? "nobody" , group ? "nogroup" , ... - }: + }: assert (lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3"); - '' - cp ${wrappedPrograms}/bin/${program}.wrapper $wrapperDir/${program} + let wrapperDrv = mkWrapper { inherit program source; }; + in '' + cp ${wrapperDrv}/bin/${program}.wrapper $wrapperDir/${program} # Prevent races chmod 0000 $wrapperDir/${program} @@ -60,8 +64,10 @@ let , setgid ? false , permissions ? "u+rx,g+x,o+x" , ... - }: '' - cp ${wrappedPrograms}/bin/${program}.wrapper $wrapperDir/${program} + }: + let wrapperDrv = mkWrapper { inherit program source; }; + in '' + cp ${wrapperDrv}/bin/${program}.wrapper $wrapperDir/${program} # Prevent races chmod 0000 $wrapperDir/${program} From 128bdac94fe8173845e162c61ddb83cb4b8ed8de Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Mon, 30 Jan 2017 12:59:29 -0600 Subject: [PATCH 64/74] Conditionally logging debug messages based on the WRAPPER_DEBUG env var being set (or not) --- nixos/modules/security/wrappers/wrapper.c | 35 ++++++++++++++--------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/nixos/modules/security/wrappers/wrapper.c b/nixos/modules/security/wrappers/wrapper.c index 608bd3a378c..e6f2605143f 100644 --- a/nixos/modules/security/wrappers/wrapper.c +++ b/nixos/modules/security/wrappers/wrapper.c @@ -26,6 +26,9 @@ extern char **environ; static char * sourceProg = SOURCE_PROG; static char * wrapperDir = WRAPPER_DIR; +// Wrapper debug variable name +static char * wrapperDebug = "WRAPPER_DEBUG"; + // Update the capabilities of the running process to include the given // capability in the Ambient set. static void set_ambient_cap(cap_value_t cap) @@ -34,7 +37,7 @@ static void set_ambient_cap(cap_value_t cap) if (capng_update(CAPNG_ADD, CAPNG_INHERITABLE, (unsigned long) cap)) { - printf("cannot raise the capability into the Inheritable set\n"); + perror("cannot raise the capability into the Inheritable set\n"); exit(1); } @@ -56,7 +59,9 @@ static int make_caps_ambient(const char *selfPath) if(!caps) { - fprintf(stderr, "no caps set or could not retrieve the caps for this file, not doing anything...\n"); + if(getenv(wrapperDebug)) + fprintf(stderr, "no caps set or could not retrieve the caps for this file, not doing anything..."); + return 1; } @@ -127,23 +132,27 @@ static int make_caps_ambient(const char *selfPath) cap_value_t capnum; if (cap_from_name(tok, &capnum)) { - fprintf(stderr, "cap_from_name failed, skipping: %s\n", tok); + if(getenv(wrapperDebug)) + fprintf(stderr, "cap_from_name failed, skipping: %s", tok); } else if (capnum == CAP_SETPCAP) { - // Check for the cap_setpcap capability, we set this on the - // wrapper so it can elevate the capabilities to the Ambient - // set but we do not want to propagate it down into the - // wrapped program. - // - // TODO: what happens if that's the behavior you want - // though???? I'm preferring a strict vs. loose policy here. - fprintf(stderr, "cap_setpcap in set, skipping it\n"); + // Check for the cap_setpcap capability, we set this on the + // wrapper so it can elevate the capabilities to the Ambient + // set but we do not want to propagate it down into the + // wrapped program. + // + // TODO: what happens if that's the behavior you want + // though???? I'm preferring a strict vs. loose policy here. + if(getenv(wrapperDebug)) + fprintf(stderr, "cap_setpcap in set, skipping it\n"); } else { - set_ambient_cap(capnum); - printf("raised %s into the Ambient capability set\n", tok); + set_ambient_cap(capnum); + + if(getenv(wrapperDebug)) + fprintf(stderr, "raised %s into the Ambient capability set\n", tok); } } cap_free(capstr); From cca2e1155617304b5bcb3457309983cf8e99b067 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Mon, 13 Feb 2017 18:03:06 -0600 Subject: [PATCH 65/74] Resurrecting the single-wrapper read from sibling .real file behavior --- nixos/modules/security/wrappers/default.nix | 44 ++++++++++----------- nixos/modules/security/wrappers/wrapper.c | 28 ++++++++----- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 757765ed08c..0548b1d9659 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 e6f2605143f..4a656c54e3f 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 .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); From a27f35993d380487d7262055aff0bfc939c235ec Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Mon, 13 Feb 2017 18:28:13 -0600 Subject: [PATCH 66/74] Derp, correctly write the source program's path --- nixos/modules/security/wrappers/default.nix | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 0548b1d9659..e51103981e6 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -27,7 +27,7 @@ let mkSetcapProgram = { program , capabilities - , source ? null + , source , owner ? "nobody" , group ? "nogroup" , ... @@ -35,7 +35,7 @@ let assert (lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3"); '' cp ${securityWrapper}/bin/security-wrapper $wrapperDir/${program} - echo -n "$source" > $wrapperDir/${program}.real + echo -n "${source}" > $wrapperDir/${program}.real # Prevent races chmod 0000 $wrapperDir/${program} @@ -53,7 +53,7 @@ let ###### Activation script for the setuid wrappers mkSetuidProgram = { program - , source ? null + , source , owner ? "nobody" , group ? "nogroup" , setuid ? false @@ -63,7 +63,7 @@ let }: '' cp ${securityWrapper}/bin/security-wrapper $wrapperDir/${program} - echo -n "$source" > $wrapperDir/${program}.real + echo -n "${source}" > $wrapperDir/${program}.real # Prevent races chmod 0000 $wrapperDir/${program} From ba499e3aa04dccd5e99676731055bf3c3a34b249 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Tue, 14 Feb 2017 07:30:21 -0600 Subject: [PATCH 67/74] Removing unused module option old-wrapperDir --- nixos/modules/security/wrappers/default.nix | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index e51103981e6..8c4353fdd96 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -131,16 +131,6 @@ in ''; }; - security.old-wrapperDir = lib.mkOption { - type = lib.types.path; - default = "/var/setuid-wrappers"; - internal = true; - description = '' - This option defines the path to the wrapper programs. It - should not be overriden. - ''; - }; - security.wrapperDir = lib.mkOption { type = lib.types.path; default = "/run/wrappers/bin"; From 467bb3f674fad56ef697bafbcc5f4db71acb036e Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Tue, 14 Feb 2017 07:32:24 -0600 Subject: [PATCH 68/74] /run/wrapper is not a filesystem, no need to skip it --- nixos/modules/installer/tools/nixos-generate-config.pl | 1 - 1 file changed, 1 deletion(-) diff --git a/nixos/modules/installer/tools/nixos-generate-config.pl b/nixos/modules/installer/tools/nixos-generate-config.pl index a1b6cf53597..b72db1f6f50 100644 --- a/nixos/modules/installer/tools/nixos-generate-config.pl +++ b/nixos/modules/installer/tools/nixos-generate-config.pl @@ -347,7 +347,6 @@ foreach my $fs (read_file("/proc/self/mountinfo")) { # Skip special filesystems. next if in($mountPoint, "/proc") || in($mountPoint, "/dev") || in($mountPoint, "/sys") || in($mountPoint, "/run") || $mountPoint eq "/var/lib/nfs/rpc_pipefs"; - next if $mountPoint eq "/run/wrappers"; # Skip the optional fields. my $n = 6; $n++ while $fields[$n] ne "-"; $n++; From fb6d13c01aa22cdaffe45597495f390ef2989eda Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Tue, 14 Feb 2017 07:38:45 -0600 Subject: [PATCH 69/74] Addressing feedback and fixing a bug --- nixos/doc/manual/release-notes/rl-1703.xml | 6 ++---- nixos/modules/module-list.nix | 2 +- nixos/modules/security/wrappers/wrapper.c | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/nixos/doc/manual/release-notes/rl-1703.xml b/nixos/doc/manual/release-notes/rl-1703.xml index 5d6053fcbf7..8f9694bad8b 100644 --- a/nixos/doc/manual/release-notes/rl-1703.xml +++ b/nixos/doc/manual/release-notes/rl-1703.xml @@ -17,10 +17,8 @@ has the following highlights: - Setting capabilities on programs is now supported with a - setcap-wrapper functionality. This - functionality and the setuid-wrapper are merged - into a single "wrappers" module. + The setuid wrapper functionality now supports setting + capabilities. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 9dbc009a6e4..81597d91d89 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -113,7 +113,7 @@ ./security/prey.nix ./security/rngd.nix ./security/rtkit.nix - ./security/wrappers + ./security/wrappers/default.nix ./security/sudo.nix ./services/amqp/activemq/default.nix ./services/amqp/rabbitmq.nix diff --git a/nixos/modules/security/wrappers/wrapper.c b/nixos/modules/security/wrappers/wrapper.c index 4a656c54e3f..7091e314bb2 100644 --- a/nixos/modules/security/wrappers/wrapper.c +++ b/nixos/modules/security/wrappers/wrapper.c @@ -165,7 +165,7 @@ int main(int argc, char * * argv) // should safely fit within the PATH_MAX system limit. Though I'm // not positive it's safe... char selfPath[PATH_MAX]; - int selfPathSize = readlink("/proc/self/exe", selfPath, sizeof(selfPath) - 1); + int selfPathSize = readlink("/proc/self/exe", selfPath, sizeof(selfPath)); assert(selfPathSize > 0); From f8b8c353ffcfb2a29178c1f7b145baebfab55f81 Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Tue, 14 Feb 2017 08:27:40 -0600 Subject: [PATCH 70/74] Simplifying the wrapper program derivation --- nixos/modules/security/wrappers/default.nix | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 8c4353fdd96..96f4544c2fa 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -9,17 +9,15 @@ let wrappers); securityWrapper = pkgs.stdenv.mkDerivation { - name = "security-wrapper"; - unpackPhase = "true"; + name = "security-wrapper"; + phases = [ "installPhase" "fixupPhase" ]; + buildInputs = [ pkgs.libcap pkgs.libcap_ng pkgs.linuxHeaders ]; + hardeningEnable = [ "pie" ]; 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 + -lcap-ng -lcap ${./wrapper.c} -o $out/bin/security-wrapper ''; }; From c01689f8dab3387eb004192ce078659e9a4f334c Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Tue, 14 Feb 2017 08:33:07 -0600 Subject: [PATCH 71/74] Fixing ref to old-wrappersDir --- nixos/modules/security/wrappers/default.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 96f4544c2fa..144053a4ea3 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -162,11 +162,11 @@ in # Remove the old /var/setuid-wrappers path from the system... # - # TDOO: this is only necessary for ugprades 16.09 => 17.x; + # TODO: this is only necessary for ugprades 16.09 => 17.x; # this conditional removal block needs to be removed after # the release. - if [ -d ${config.security.old-wrapperDir} ]; then - rm -rf ${config.security.old-wrapperDir} + if [ -d /var/setuid-wrappers ]; then + rm -rf /var/setuid-wrappers fi # Remove the old /run/setuid-wrappers-dir path from the From e856d6efe812f24034aa8077fb538af0e8f8462d Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Tue, 14 Feb 2017 08:40:12 -0600 Subject: [PATCH 72/74] Default should be to set owner and group to root on setcap wrappers too --- nixos/modules/security/wrappers/default.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 144053a4ea3..2ed8a601a03 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -73,7 +73,10 @@ let mkWrappedPrograms = builtins.map (s: if (s ? "capabilities") - then mkSetcapProgram s + then mkSetcapProgram + ({ owner = "root"; + , group = "root"; + } // s) else if (s ? "setuid" && s.setuid == true) || (s ? "setguid" && s.setguid == true) || From 794b3721bc8bd06169b23ed923ce45905a1baf7b Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Tue, 14 Feb 2017 08:42:08 -0600 Subject: [PATCH 73/74] Syntax wibble --- nixos/modules/security/wrappers/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 2ed8a601a03..6f93403960a 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -75,7 +75,7 @@ let (s: if (s ? "capabilities") then mkSetcapProgram ({ owner = "root"; - , group = "root"; + group = "root"; } // s) else if (s ? "setuid" && s.setuid == true) || From 69794e333a41f3d7d0de44da790c5d356c58e28b Mon Sep 17 00:00:00 2001 From: Parnell Springmeyer Date: Tue, 14 Feb 2017 08:53:30 -0600 Subject: [PATCH 74/74] Using para tags for manual formatting --- nixos/modules/security/wrappers/default.nix | 31 +++++++++++---------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix index 6f93403960a..c5b99c0c801 100644 --- a/nixos/modules/security/wrappers/default.nix +++ b/nixos/modules/security/wrappers/default.nix @@ -109,26 +109,27 @@ in }; }; description = '' - This option allows the ownership and permissions on the setuid - wrappers for specific programs to be overridden from the - default (setuid root, but not setgid root). + This option allows the ownership and permissions on the + setuid wrappers for specific programs to be overridden from + the default (setuid root, but not setgid root). - Additionally, this option can set capabilities on a wrapper - program that propagates those capabilities down to the - wrapped, real program. + Additionally, this option can set capabilities on a + wrapper program that propagates those capabilities down to the + wrapped, real program. - The program attribute is the name of the - program to be wrapped. If no source + The program attribute is the name of + the program to be wrapped. If no source attribute is provided, specifying the absolute path to the program, then the program will be searched for in the path - environment variable. + environment variable. - NOTE: cap_setpcap, which is required for the wrapper program - to be able to raise caps into the Ambient set is NOT raised to - the Ambient set so that the real program cannot modify its own - capabilities!! This may be too restrictive for cases in which - the real program needs cap_setpcap but it at least leans on - the side security paranoid vs. too relaxed. + NOTE: cap_setpcap, which is required for the wrapper + program to be able to raise caps into the Ambient set is NOT + raised to the Ambient set so that the real program cannot + modify its own capabilities!! This may be too restrictive for + cases in which the real program needs cap_setpcap but it at + least leans on the side security paranoid vs. too + relaxed. ''; };