Merge pull request #16654 from awakenetworks/parnell/setcap-wrappers

Adding setcap-wrapper functionality to Nix
This commit is contained in:
Eelco Dolstra 2017-02-14 16:25:06 +01:00 committed by GitHub
commit 314dd9215b
69 changed files with 611 additions and 375 deletions

View File

@ -16,6 +16,11 @@ has the following highlights: </para>
manual</link> for more information.</para>
</listitem>
<listitem>
<para>The setuid wrapper functionality now supports setting
capabilities.</para>
</listitem>
<listitem>
<para>X.org server uses branch 1.19. Due to ABI incompatibilities,
<literal>ati_unfree</literal> keeps forcing 1.17

View File

@ -168,7 +168,7 @@ in
${cfg.extraInit}
# The setuid wrappers override other bin directories.
# The setuid/setcap wrappers override other bin directories.
export PATH="${config.security.wrapperDir}:$PATH"
# ~/bin if it exists overrides other bin directories.

View File

@ -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 "/var/setuid-wrappers";
# Skip the optional fields.
my $n = 6; $n++ while $fields[$n] ne "-"; $n++;

View File

@ -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 /var/setuid-wrappers/passwd ] && [ -t 0 ]; then
if [ -z "$noRootPasswd" ] && chroot $mountPoint [ -x /run/wrappers/bin/passwd ] && [ -t 0 ]; then
echo "setting root password..."
chroot $mountPoint /var/setuid-wrappers/passwd
chroot $mountPoint /run/wrappers/bin/passwd
fi

View File

@ -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; };

View File

@ -113,7 +113,7 @@
./security/prey.nix
./security/rngd.nix
./security/rtkit.nix
./security/setuid-wrappers.nix
./security/wrappers/default.nix
./security/sudo.nix
./services/amqp/activemq/default.nix
./services/amqp/rabbitmq.nix

View File

@ -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";
};
}

View File

@ -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";
};
}

View File

@ -101,11 +101,15 @@ in
chpasswd = { rootOK = true; };
};
security.setuidPrograms = [ "su" "chfn" ]
++ [ "newuidmap" "newgidmap" ] # new in shadow 4.2.x
++ 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";
} // (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 {});
};
}

View File

@ -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" ])

View File

@ -19,7 +19,7 @@ with lib;
config = mkIf (cfg.confineSUIDApplications) {
security.apparmor.profiles = [ (pkgs.writeText "ping" ''
#include <tunables/global>
/var/setuid-wrappers/ping {
/run/wrappers/bin/ping {
#include <abstractions/base>
#include <abstractions/consoles>
#include <abstractions/nameservice>
@ -33,7 +33,6 @@ with lib;
${pkgs.attr.out}/lib/libattr.so* mr,
${pkgs.iputils}/bin/ping mixr,
/var/setuid-wrappers/ping.real r,
#/etc/modules.conf r,

View File

@ -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}";
};
}

View File

@ -187,7 +187,8 @@ 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.

View File

@ -472,19 +472,20 @@ 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.wrappers = {
unix_chkpwd = {
source = "${pkgs.pam}/sbin/unix_chkpwd.orig";
owner = "root";
setuid = true;
};
} // (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;
security.setuidOwners = [ {
program = "unix_chkpwd";
source = "${pkgs.pam}/sbin/unix_chkpwd.orig";
owner = "root";
setuid = true;
} ];
security.pam.services =
{ other.text =
''

View File

@ -32,10 +32,12 @@ 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.wrappers = {
pmount.source = "${pkgs.pmount.out}/bin/pmount";
pumount.source = "${pkgs.pmount.out}/bin/pumount";
};
security.setuidPrograms = [ "pmount" "pumount" ];
environment.systemPackages = [ pkgs.pmount ];
};

View File

@ -83,16 +83,10 @@ in
security.pam.services.polkit-1 = {};
security.setuidPrograms = [ "pkexec" ];
security.setuidOwners = [
{ program = "polkit-agent-helper-1";
owner = "root";
group = "root";
setuid = true;
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 =
''

View File

@ -1,81 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
/* 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 <self>.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);
}

View File

@ -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 <option>wrapperDir</option> is
<filename>/var/setuid-wrappers</filename>.
'';
};
};
###### 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
'';
};
}

View File

@ -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 ];

View File

@ -0,0 +1,216 @@
{ config, lib, pkgs, ... }:
let
inherit (config.security) wrapperDir wrappers setuidPrograms;
programs =
(lib.mapAttrsToList
(n: v: (if v ? "program" then v else v // {program=n;}))
wrappers);
securityWrapper = pkgs.stdenv.mkDerivation {
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\" \
-lcap-ng -lcap ${./wrapper.c} -o $out/bin/security-wrapper
'';
};
###### Activation script for the setcap wrappers
mkSetcapProgram =
{ program
, capabilities
, source
, owner ? "nobody"
, group ? "nogroup"
, ...
}:
assert (lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3");
''
cp ${securityWrapper}/bin/security-wrapper $wrapperDir/${program}
echo -n "${source}" > $wrapperDir/${program}.real
# 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.
${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
, owner ? "nobody"
, group ? "nogroup"
, setuid ? false
, setgid ? false
, permissions ? "u+rx,g+x,o+x"
, ...
}:
''
cp ${securityWrapper}/bin/security-wrapper $wrapperDir/${program}
echo -n "${source}" > $wrapperDir/${program}.real
# 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}
'';
mkWrappedPrograms =
builtins.map
(s: if (s ? "capabilities")
then mkSetcapProgram
({ owner = "root";
group = "root";
} // s)
else if
(s ? "setuid" && s.setuid == true) ||
(s ? "setguid" && s.setguid == true) ||
(s ? "permissions")
then mkSetuidProgram s
else mkSetuidProgram
({ owner = "root";
group = "root";
setuid = true;
setgid = false;
permissions = "u+rx,g+x,o+x";
} // s)
) programs;
in
{
###### interface
options = {
security.wrappers = lib.mkOption {
type = lib.types.attrs;
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 = ''
<para>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).</para>
<para>Additionally, this option can set capabilities on a
wrapper program that propagates those capabilities down to the
wrapped, real program.</para>
<para>The <literal>program</literal> attribute is the name of
the program to be wrapped. If no <literal>source</literal>
attribute is provided, specifying the absolute path to the
program, then the program will be searched for in the path
environment variable.</para>
<para>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.</para>
'';
};
security.wrapperDir = lib.mkOption {
type = lib.types.path;
default = "/run/wrappers/bin";
internal = true;
description = ''
This option defines the path to the wrapper programs. It
should not be overriden.
'';
};
};
###### 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 = ''
# Wrappers override other bin directories.
export PATH="${wrapperDir}:$PATH"
'';
###### setcap activation script
system.activationScripts.wrappers =
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
# Remove the old /var/setuid-wrappers path from the system...
#
# TODO: this is only necessary for ugprades 16.09 => 17.x;
# this conditional removal block needs to be removed after
# the release.
if [ -d /var/setuid-wrappers ]; then
rm -rf /var/setuid-wrappers
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-wrapper-dirs ]; then
rm -rf /run/setuid-wrapper-dirs
fi
# Get the "/run/wrappers" path, we want to place the tmpdirs
# for the wrappers there
parentWrapperDir="$(dirname ${wrapperDir})"
mkdir -p "$parentWrapperDir"
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 -f ${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
'';
};
}

View File

@ -0,0 +1,239 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <assert.h>
#include <errno.h>
#include <linux/capability.h>
#include <sys/capability.h>
#include <linux/prctl.h>
#include <sys/prctl.h>
#include <cap-ng.h>
// 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 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
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)
{
capng_get_caps_process();
if (capng_update(CAPNG_ADD, CAPNG_INHERITABLE, (unsigned long) cap))
{
perror("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)
{
if(getenv(wrapperDebug))
fprintf(stderr, "no caps set or could not retrieve the caps for this file, not doing anything...");
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))
{
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.
if(getenv(wrapperDebug))
fprintf(stderr, "cap_setpcap in set, skipping it\n");
}
else
{
set_ambient_cap(capnum);
if(getenv(wrapperDebug))
fprintf(stderr, "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));
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,
// 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)));
// Read the path of the real (wrapped) program from <self>.real.
char realFN[PATH_MAX + 10];
int realFNSize = snprintf (realFN, sizeof(realFN), "%s.real", selfPath);
assert (realFNSize < sizeof(realFN));
int fdSelf = open(realFN, O_RDONLY);
assert (fdSelf != -1);
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);
execve(sourceProg, argv, environ);
fprintf(stderr, "%s: cannot run `%s': %s\n",
argv[0], sourceProg, strerror(errno));
exit(1);
}

View File

@ -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=/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, ...}:

View File

@ -13,7 +13,7 @@ let
''
base_dir = ${baseDir}
protocols = ${concatStringsSep " " cfg.protocols}
sendmail_path = /var/setuid-wrappers/sendmail
sendmail_path = /run/wrappers/bin/sendmail
''
(if isNull cfg.sslServerCert then ''

View File

@ -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 = /run/wrappers/bin/exim
spool_directory = ${cfg.spoolDir}
${cfg.config}
'';
@ -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";

View File

@ -26,7 +26,7 @@ with lib;
config = mkIf (config.services.mail.sendmailSetuidWrapper != null) {
security.setuidOwners = [ config.services.mail.sendmailSetuidWrapper ];
security.wrappers.sendmail = config.services.mail.sendmailSetuidWrapper;
};

View File

@ -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 "/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="/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="/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/";

View File

@ -124,7 +124,7 @@ in
};
mailer = mkOption {
default = "/var/setuid-wrappers/sendmail";
default = "/run/wrappers/bin/sendmail";
type = types.path;
description = ''
Sendmail-compatible binary to be used to send the messages.

View File

@ -30,7 +30,7 @@ let
''
[ global ]
security = ${cfg.securityType}
passwd program = /var/setuid-wrappers/passwd %u
passwd program = /run/wrappers/bin/passwd %u
pam password change = ${smbToString cfg.syncPasswordsByPam}
invalid users = ${smbToString cfg.invalidUsers}

View File

@ -141,7 +141,7 @@ in
setgid = false;
};
security.setuidOwners = [ cfg.setuidWrapper ];
security.wrappers.gksign = cfg.setuidWrapper;
systemd.services.gale-galed = {
description = "Gale messaging daemon";

View File

@ -18,7 +18,7 @@ let
var_prefix = "${stateDir}"
prayer_user = "${prayerUser}"
prayer_group = "${prayerGroup}"
sendmail_path = "/var/setuid-wrappers/sendmail"
sendmail_path = "/run/wrappers/bin/sendmail"
use_http_port ${cfg.port}

View File

@ -226,7 +226,7 @@ in
sendmail = mkOption {
type = types.nullOr types.path;
default = null;
example = "/var/setuid-wrappers/sendmail";
example = "/run/wrappers/bin/sendmail";
description = "Use this sendmail compatible script to deliver alerts";
};
smokeMailTemplate = mkOption {
@ -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;

View File

@ -42,13 +42,13 @@ in
config = mkIf cfg.enable {
security.setuidOwners = map (program: {
inherit 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 ];

View File

@ -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 = "/run/wrappers/bin/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 <option>security.setuidOwners</option>
sendmail. See <option>security.wrappers</option>
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,13 +92,9 @@ in
config = mkMerge [
{ 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; }
''

View File

@ -96,7 +96,7 @@ in
fcronallow = /etc/fcron.allow
fcrondeny = /etc/fcron.deny
shell = /bin/sh
sendmail = /var/setuid-wrappers/sendmail
sendmail = /run/wrappers/bin/sendmail
editor = /run/current-system/sw/bin/vi
'';
target = "fcron.conf";
@ -106,8 +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" ];

View File

@ -104,15 +104,14 @@ in
systemd.packages = [ pkgs.dbus.daemon ];
security.setuidOwners = 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

View File

@ -62,7 +62,7 @@ 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";

View File

@ -61,24 +61,13 @@ in
''}
exec "${kde5.startkde}"
'';
};
security.setuidOwners = [
{
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 =
[

View File

@ -1,4 +1,4 @@
{ config, lib, pkgs, utils, ... }:
{ config, lib, pkgs, utils, stdenv, ... }:
with lib;
with utils;
@ -933,7 +933,22 @@ 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.wrappers = if (versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.3") then {
ping = {
source = "${pkgs.iputils.out}/bin/ping";
capabilities = "cap_net_raw+p";
};
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
# clear it if it's not configured in the NixOS configuration,

View File

@ -68,14 +68,13 @@ in
boot.extraModulePackages = [ kernelModules ];
environment.systemPackages = [ virtualbox ];
security.setuidOwners = let
mkSuid = program: {
inherit program;
security.wrappers = let
mkSuid = program: {"${program}" = {
source = "${virtualbox}/libexec/virtualbox/${program}";
owner = "root";
group = "vboxusers";
setuid = true;
};
};};
in mkIf cfg.enableHardening (map mkSuid [
"VBoxHeadless"
"VBoxNetAdpCtl"
@ -99,7 +98,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";

View File

@ -14,7 +14,7 @@ import ./make-test.nix ({ pkgs, ...} : {
mailHost = "127.0.0.2";
probeConfig = ''
+ FPing
binary = /var/setuid-wrappers/fping
binary = /run/wrappers/bin/fping
offset = 0%
'';
};

View File

@ -1,5 +1,5 @@
{ fetchurl, stdenv, glib, xorg, cairo, gtk2, pango, makeWrapper, openssl, bzip2,
pkexecPath ? "/var/setuid-wrappers/pkexec", libredirect,
pkexecPath ? "/run/wrappers/bin/pkexec", libredirect,
gksuSupport ? false, gksu}:
assert stdenv.system == "i686-linux" || stdenv.system == "x86_64-linux";

View File

@ -83,9 +83,9 @@ in stdenv.mkDerivation {
ed -v -s "$out/bin/chromium" << EOF
2i
if [ -x "/var/setuid-wrappers/${sandboxExecutableName}" ]
if [ -x "/run/wrappers/bin/${sandboxExecutableName}" ]
then
export CHROME_DEVEL_SANDBOX="/var/setuid-wrappers/${sandboxExecutableName}"
export CHROME_DEVEL_SANDBOX="/run/wrappers/bin/${sandboxExecutableName}"
else
export CHROME_DEVEL_SANDBOX="$sandbox/bin/${sandboxExecutableName}"
fi

View File

@ -26,7 +26,7 @@ index 50e8ad8..eec0ed2 100644
+ is_nixos=no
+fi
+
+if [ -u /var/setuid-wrappers/gksign ]; then
+if [ -u /run/wrappers/bin/gksign ]; then
+ cat <<EOM
+
+Gale appears to have already been set up via the NixOS module system (check

View File

@ -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 setuid-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 setuid-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) {

View File

@ -11,7 +11,7 @@ index a9d8ac4..85f13f5 100644
- # # arguments: '-i -t'
- # # }
+ config.action_mailer.sendmail_settings = {
+ location: '/var/setuid-wrappers/sendmail',
+ location: '/run/wrappers/bin/sendmail',
+ arguments: '-i -t'
+ }
config.action_mailer.perform_deliveries = true

View File

@ -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, "/run/wrappers/bin");
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, "/run/wrappers/bin");
+}
+
+
@ -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 "/run/wrappers/bin/"
+
+RTR3DECL(char *) RTProcGetSuidPath(char *pszExecPath, size_t cbExecPath)
+{

View File

@ -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='/run/wrappers/bin:/usr/bin:/usr/sbin'
export PKG_CONFIG_PATH=/usr/lib/pkgconfig
# Force compilers to look in default search paths

View File

@ -42,13 +42,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. wrappers.setuid detects it and places wrappers in /run/wrappers/bin/e_freqset,
# 4. and finally, links /run/wrappers/bin/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 /run/wrappers/bin/e_freqset $CPUFREQ_DIRPATH/freqset
'';
meta = with stdenv.lib; {

View File

@ -7,7 +7,7 @@ Index: kinit-5.24.0/src/start_kdeinit/start_kdeinit_wrapper.c
#include <unistd.h>
-#define EXECUTE CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/start_kdeinit"
+#define EXECUTE "/var/setuid-wrappers/start_kdeinit"
+#define EXECUTE "/run/wrappers/bin/start_kdeinit"
#if KDEINIT_OOM_PROTECT

View File

@ -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|/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
'';

View File

@ -5,7 +5,7 @@
let
system = "/var/run/current-system/sw";
setuid = "/var/setuid-wrappers"; #TODO: from <nixos> config.security.wrapperDir;
setuid = "/run/wrappers/bin"; #TODO: from <nixos> config.security.wrapperDir;
foolVars = {
SYSCONF = "/etc";

View File

@ -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 /run/wrappers/bin/${chromium.sandboxExecutableName} $unitydir/chrome-sandbox
mkdir -p $out/share/applications
sed "/^Exec=/c\Exec=$out/bin/unity-editor" \

View File

@ -28,7 +28,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=\"/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

View File

@ -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@/run/wrappers/bin/sendmail@' -i Makefile
'';
meta = {

View File

@ -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@/run/wrappers/bin/sendmail@' -i Makefile
'';
meta = {

View File

@ -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 /run/wrappers/bin/unix_chkpwd $out/sbin/unix_chkpwd
''; /*
rm -rf $out/etc
mkdir -p $modules/lib

View File

@ -36,7 +36,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=/run/wrappers/bin:/var/run/current-system/sw/bin:/sbin
${if ncurses == null then "--without-ncurses" else ""}
${if systemd == null then "" else ''
--with-systemd

View File

@ -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|/run/wrappers/bin/sudo|' \
-e 's|/sbin/cryptsetup|${cryptsetup}/bin/cryptsetup|'
'';
}

View File

@ -1,4 +1,4 @@
{ stdenv, fetchurl, flex, bison, sendmailPath ? "/var/setuid-wrappers/sendmail" }:
{ stdenv, fetchurl, flex, bison, sendmailPath ? "/run/wrappers/bin/sendmail" }:
stdenv.mkDerivation rec {
name = "petidomo-4.3";

View File

@ -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='/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'
)
";

View File

@ -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"' '"/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|/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|/run/wrappers/bin/su|g' x11vnc/ssltools.h
'';
meta = {

View File

@ -31,7 +31,7 @@ python2Packages.buildPythonApplication rec {
buildInputs = [ dialog ] ++ (with python2Packages; [ nose mock gnureadline ]);
patchPhase = ''
substituteInPlace certbot/notify.py --replace "/usr/sbin/sendmail" "/var/setuid-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"
'';

View File

@ -2,7 +2,7 @@
, FileDesktopEntry, libxslt, docbook_xsl, makeWrapper
, python3Packages
, perlPackages, curl, gnupg, diffutils
, sendmailPath ? "/var/setuid-wrappers/sendmail"
, sendmailPath ? "/run/wrappers/bin/sendmail"
}:
let

View File

@ -11,7 +11,7 @@ stdenv.mkDerivation rec {
};
# TODO: replace wrapperDir below with from <nixos> config.security.wrapperDir;
wrapperDir = "/var/setuid-wrappers";
wrapperDir = "/run/wrappers/bin";
postPatch = ''
FILES="$(grep -r '/bin/sh' src/utils -l; find src -name \*.c)"

View File

@ -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 /run/wrappers/bin
installPhase = ''
mkdir -p $out/bin $out/libexec
cp $src $out/libexec/ecryptfs-helper.py

View File

@ -1,5 +1,5 @@
{ stdenv, fetchurl, coreutils, pam, groff
, sendmailPath ? "/var/setuid-wrappers/sendmail"
, sendmailPath ? "/run/wrappers/bin/sendmail"
, withInsults ? false
}:

View File

@ -1,4 +1,4 @@
{ fetchurl, stdenv, bison, flex, pam, sendmailPath ? "/var/setuid-wrappers/sendmail" }:
{ fetchurl, stdenv, bison, flex, pam, sendmailPath ? "/run/wrappers/bin/sendmail" }:
stdenv.mkDerivation {
name = "at-3.1.16";

View File

@ -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 "/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

View File

@ -1,5 +1,5 @@
{stdenv, fetchurl,
sendmailPath ? "/var/setuid-wrappers/sendmail" }:
sendmailPath ? "/run/wrappers/bin/sendmail" }:
stdenv.mkDerivation rec {