Merge pull request #16654 from awakenetworks/parnell/setcap-wrappers
Adding setcap-wrapper functionality to Nix
This commit is contained in:
commit
314dd9215b
@ -16,6 +16,11 @@ has the following highlights: </para>
|
|||||||
manual</link> for more information.</para>
|
manual</link> for more information.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>The setuid wrapper functionality now supports setting
|
||||||
|
capabilities.</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>X.org server uses branch 1.19. Due to ABI incompatibilities,
|
<para>X.org server uses branch 1.19. Due to ABI incompatibilities,
|
||||||
<literal>ati_unfree</literal> keeps forcing 1.17
|
<literal>ati_unfree</literal> keeps forcing 1.17
|
||||||
|
@ -168,7 +168,7 @@ in
|
|||||||
|
|
||||||
${cfg.extraInit}
|
${cfg.extraInit}
|
||||||
|
|
||||||
# The setuid wrappers override other bin directories.
|
# The setuid/setcap wrappers override other bin directories.
|
||||||
export PATH="${config.security.wrapperDir}:$PATH"
|
export PATH="${config.security.wrapperDir}:$PATH"
|
||||||
|
|
||||||
# ~/bin if it exists overrides other bin directories.
|
# ~/bin if it exists overrides other bin directories.
|
||||||
|
@ -347,7 +347,6 @@ foreach my $fs (read_file("/proc/self/mountinfo")) {
|
|||||||
|
|
||||||
# Skip special filesystems.
|
# 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 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.
|
# Skip the optional fields.
|
||||||
my $n = 6; $n++ while $fields[$n] ne "-"; $n++;
|
my $n = 6; $n++ while $fields[$n] ne "-"; $n++;
|
||||||
|
@ -259,9 +259,9 @@ chroot $mountPoint /nix/var/nix/profiles/system/activate
|
|||||||
|
|
||||||
|
|
||||||
# Ask the user to set a root password.
|
# 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..."
|
echo "setting root password..."
|
||||||
chroot $mountPoint /var/setuid-wrappers/passwd
|
chroot $mountPoint /run/wrappers/bin/passwd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
@ -103,15 +103,16 @@ in {
|
|||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
users.extraGroups = mkIf isMLocate { mlocate = {}; };
|
users.extraGroups = mkIf isMLocate { mlocate = {}; };
|
||||||
|
|
||||||
security.setuidOwners = mkIf isMLocate
|
security.wrappers = mkIf isMLocate {
|
||||||
[ { group = "mlocate";
|
mlocate = {
|
||||||
|
group = "mlocate";
|
||||||
owner = "root";
|
owner = "root";
|
||||||
permissions = "u+rx,g+x,o+x";
|
permissions = "u+rx,g+x,o+x";
|
||||||
setgid = true;
|
setgid = true;
|
||||||
setuid = false;
|
setuid = false;
|
||||||
program = "locate";
|
program = "locate";
|
||||||
}
|
};
|
||||||
];
|
};
|
||||||
|
|
||||||
nixpkgs.config = { locate.dbfile = cfg.output; };
|
nixpkgs.config = { locate.dbfile = cfg.output; };
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@
|
|||||||
./security/prey.nix
|
./security/prey.nix
|
||||||
./security/rngd.nix
|
./security/rngd.nix
|
||||||
./security/rtkit.nix
|
./security/rtkit.nix
|
||||||
./security/setuid-wrappers.nix
|
./security/wrappers/default.nix
|
||||||
./security/sudo.nix
|
./security/sudo.nix
|
||||||
./services/amqp/activemq/default.nix
|
./services/amqp/activemq/default.nix
|
||||||
./services/amqp/rabbitmq.nix
|
./services/amqp/rabbitmq.nix
|
||||||
|
@ -11,6 +11,6 @@ in
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
environment.systemPackages = [ pkgs.kbdlight ];
|
environment.systemPackages = [ pkgs.kbdlight ];
|
||||||
security.setuidPrograms = [ "kbdlight" ];
|
security.wrappers.kbdlight.source = "${pkgs.kbdlight.out}/bin/kbdlight";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,6 @@ in
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
environment.systemPackages = [ pkgs.light ];
|
environment.systemPackages = [ pkgs.light ];
|
||||||
security.setuidPrograms = [ "light" ];
|
security.wrappers.light.source = "${pkgs.light.out}/bin/light";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -101,11 +101,15 @@ in
|
|||||||
chpasswd = { rootOK = true; };
|
chpasswd = { rootOK = true; };
|
||||||
};
|
};
|
||||||
|
|
||||||
security.setuidPrograms = [ "su" "chfn" ]
|
security.wrappers = {
|
||||||
++ [ "newuidmap" "newgidmap" ] # new in shadow 4.2.x
|
su.source = "${pkgs.shadow.su}/bin/su";
|
||||||
++ lib.optionals config.users.mutableUsers
|
chfn.source = "${pkgs.shadow.out}/bin/chfn";
|
||||||
[ "passwd" "sg" "newgrp" ];
|
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 {});
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ with lib;
|
|||||||
(mkRenamedOptionModule [ "fonts" "enableFontConfig" ] [ "fonts" "fontconfig" "enable" ])
|
(mkRenamedOptionModule [ "fonts" "enableFontConfig" ] [ "fonts" "fontconfig" "enable" ])
|
||||||
(mkRenamedOptionModule [ "fonts" "extraFonts" ] [ "fonts" "fonts" ])
|
(mkRenamedOptionModule [ "fonts" "extraFonts" ] [ "fonts" "fonts" ])
|
||||||
|
|
||||||
(mkRenamedOptionModule [ "security" "extraSetuidPrograms" ] [ "security" "setuidPrograms" ])
|
|
||||||
(mkRenamedOptionModule [ "networking" "enableWLAN" ] [ "networking" "wireless" "enable" ])
|
(mkRenamedOptionModule [ "networking" "enableWLAN" ] [ "networking" "wireless" "enable" ])
|
||||||
(mkRenamedOptionModule [ "networking" "enableRT73Firmware" ] [ "networking" "enableRalinkFirmware" ])
|
(mkRenamedOptionModule [ "networking" "enableRT73Firmware" ] [ "networking" "enableRalinkFirmware" ])
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ with lib;
|
|||||||
config = mkIf (cfg.confineSUIDApplications) {
|
config = mkIf (cfg.confineSUIDApplications) {
|
||||||
security.apparmor.profiles = [ (pkgs.writeText "ping" ''
|
security.apparmor.profiles = [ (pkgs.writeText "ping" ''
|
||||||
#include <tunables/global>
|
#include <tunables/global>
|
||||||
/var/setuid-wrappers/ping {
|
/run/wrappers/bin/ping {
|
||||||
#include <abstractions/base>
|
#include <abstractions/base>
|
||||||
#include <abstractions/consoles>
|
#include <abstractions/consoles>
|
||||||
#include <abstractions/nameservice>
|
#include <abstractions/nameservice>
|
||||||
@ -33,7 +33,6 @@ with lib;
|
|||||||
${pkgs.attr.out}/lib/libattr.so* mr,
|
${pkgs.attr.out}/lib/libattr.so* mr,
|
||||||
|
|
||||||
${pkgs.iputils}/bin/ping mixr,
|
${pkgs.iputils}/bin/ping mixr,
|
||||||
/var/setuid-wrappers/ping.real r,
|
|
||||||
|
|
||||||
#/etc/modules.conf r,
|
#/etc/modules.conf r,
|
||||||
|
|
||||||
|
@ -27,6 +27,6 @@ in
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
environment.systemPackages = [ sandbox ];
|
environment.systemPackages = [ sandbox ];
|
||||||
security.setuidPrograms = [ sandbox.passthru.sandboxExecutableName ];
|
security.wrappers."${sandbox.passthru.sandboxExecutableName}".source = "${sandbox}/bin/${sandbox.passthru.sandboxExecutableName}";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,8 @@ in
|
|||||||
];
|
];
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.duo-unix ];
|
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;
|
environment.etc = loginCfgFile ++ pamCfgFile;
|
||||||
|
|
||||||
/* If PAM *and* SSH are enabled, then don't do anything special.
|
/* If PAM *and* SSH are enabled, then don't do anything special.
|
||||||
|
@ -472,18 +472,19 @@ in
|
|||||||
++ optionals config.security.pam.enableU2F [ pkgs.pam_u2f ]
|
++ optionals config.security.pam.enableU2F [ pkgs.pam_u2f ]
|
||||||
++ optionals config.security.pam.enableEcryptfs [ pkgs.ecryptfs ];
|
++ optionals config.security.pam.enableEcryptfs [ pkgs.ecryptfs ];
|
||||||
|
|
||||||
security.setuidPrograms =
|
security.wrappers = {
|
||||||
optionals config.security.pam.enableEcryptfs [ "mount.ecryptfs_private" "umount.ecryptfs_private" ];
|
unix_chkpwd = {
|
||||||
|
|
||||||
environment.etc =
|
|
||||||
mapAttrsToList (n: v: makePAMService v) config.security.pam.services;
|
|
||||||
|
|
||||||
security.setuidOwners = [ {
|
|
||||||
program = "unix_chkpwd";
|
|
||||||
source = "${pkgs.pam}/sbin/unix_chkpwd.orig";
|
source = "${pkgs.pam}/sbin/unix_chkpwd.orig";
|
||||||
owner = "root";
|
owner = "root";
|
||||||
setuid = true;
|
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.pam.services =
|
security.pam.services =
|
||||||
{ other.text =
|
{ other.text =
|
||||||
|
@ -32,10 +32,12 @@ in
|
|||||||
|
|
||||||
config = mkIf (cfg.enable || anyUsbAuth) {
|
config = mkIf (cfg.enable || anyUsbAuth) {
|
||||||
|
|
||||||
# pmount need to have a set-uid bit to make pam_usb works in user
|
# Make sure pmount and pumount are setuid wrapped.
|
||||||
# environment. (like su, sudo)
|
security.wrappers = {
|
||||||
|
pmount.source = "${pkgs.pmount.out}/bin/pmount";
|
||||||
|
pumount.source = "${pkgs.pmount.out}/bin/pumount";
|
||||||
|
};
|
||||||
|
|
||||||
security.setuidPrograms = [ "pmount" "pumount" ];
|
|
||||||
environment.systemPackages = [ pkgs.pmount ];
|
environment.systemPackages = [ pkgs.pmount ];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -83,16 +83,10 @@ in
|
|||||||
|
|
||||||
security.pam.services.polkit-1 = {};
|
security.pam.services.polkit-1 = {};
|
||||||
|
|
||||||
security.setuidPrograms = [ "pkexec" ];
|
security.wrappers = {
|
||||||
|
pkexec.source = "${pkgs.polkit.out}/bin/pkexec";
|
||||||
security.setuidOwners = [
|
"polkit-agent-helper-1".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 =
|
system.activationScripts.polkit =
|
||||||
''
|
''
|
||||||
|
@ -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);
|
|
||||||
}
|
|
@ -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
|
|
||||||
'';
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -81,7 +81,10 @@ in
|
|||||||
${cfg.extraConfig}
|
${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 ];
|
environment.systemPackages = [ sudo ];
|
||||||
|
|
||||||
|
216
nixos/modules/security/wrappers/default.nix
Normal file
216
nixos/modules/security/wrappers/default.nix
Normal 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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
239
nixos/modules/security/wrappers/wrapper.c
Normal file
239
nixos/modules/security/wrappers/wrapper.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -29,8 +29,8 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
cronJob = ''
|
cronJob = ''
|
||||||
@reboot logcheck env PATH=/var/setuid-wrappers:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck -R ${flags}
|
@reboot logcheck env PATH=/run/wrappers/bin:$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}
|
2 ${cfg.timeOfDay} * * * logcheck env PATH=/run/wrappers/bin:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck ${flags}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
writeIgnoreRule = name: {level, regex, ...}:
|
writeIgnoreRule = name: {level, regex, ...}:
|
||||||
|
@ -13,7 +13,7 @@ let
|
|||||||
''
|
''
|
||||||
base_dir = ${baseDir}
|
base_dir = ${baseDir}
|
||||||
protocols = ${concatStringsSep " " cfg.protocols}
|
protocols = ${concatStringsSep " " cfg.protocols}
|
||||||
sendmail_path = /var/setuid-wrappers/sendmail
|
sendmail_path = /run/wrappers/bin/sendmail
|
||||||
''
|
''
|
||||||
|
|
||||||
(if isNull cfg.sslServerCert then ''
|
(if isNull cfg.sslServerCert then ''
|
||||||
|
@ -70,7 +70,7 @@ in
|
|||||||
etc."exim.conf".text = ''
|
etc."exim.conf".text = ''
|
||||||
exim_user = ${cfg.user}
|
exim_user = ${cfg.user}
|
||||||
exim_group = ${cfg.group}
|
exim_group = ${cfg.group}
|
||||||
exim_path = /var/setuid-wrappers/exim
|
exim_path = /run/wrappers/bin/exim
|
||||||
spool_directory = ${cfg.spoolDir}
|
spool_directory = ${cfg.spoolDir}
|
||||||
${cfg.config}
|
${cfg.config}
|
||||||
'';
|
'';
|
||||||
@ -89,7 +89,7 @@ in
|
|||||||
gid = config.ids.gids.exim;
|
gid = config.ids.gids.exim;
|
||||||
};
|
};
|
||||||
|
|
||||||
security.setuidPrograms = [ "exim" ];
|
security.wrappers.exim.source = "${exim}/bin/exim";
|
||||||
|
|
||||||
systemd.services.exim = {
|
systemd.services.exim = {
|
||||||
description = "Exim Mail Daemon";
|
description = "Exim Mail Daemon";
|
||||||
|
@ -26,7 +26,7 @@ with lib;
|
|||||||
|
|
||||||
config = mkIf (config.services.mail.sendmailSetuidWrapper != null) {
|
config = mkIf (config.services.mail.sendmailSetuidWrapper != null) {
|
||||||
|
|
||||||
security.setuidOwners = [ config.services.mail.sendmailSetuidWrapper ];
|
security.wrappers.sendmail = config.services.mail.sendmailSetuidWrapper;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ let
|
|||||||
cap=$(sed -nr 's/.*#%#\s+capabilities\s*=\s*(.+)/\1/p' $file)
|
cap=$(sed -nr 's/.*#%#\s+capabilities\s*=\s*(.+)/\1/p' $file)
|
||||||
|
|
||||||
wrapProgram $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_LIBDIR "${pkgs.munin}/lib" \
|
||||||
--set MUNIN_PLUGSTATE "/var/run/munin"
|
--set MUNIN_PLUGSTATE "/var/run/munin"
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ in
|
|||||||
|
|
||||||
mkdir -p /etc/munin/plugins
|
mkdir -p /etc/munin/plugins
|
||||||
rm -rf /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 = {
|
serviceConfig = {
|
||||||
ExecStart = "${pkgs.munin}/sbin/munin-node --config ${nodeConf} --servicedir /etc/munin/plugins/";
|
ExecStart = "${pkgs.munin}/sbin/munin-node --config ${nodeConf} --servicedir /etc/munin/plugins/";
|
||||||
|
@ -124,7 +124,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
mailer = mkOption {
|
mailer = mkOption {
|
||||||
default = "/var/setuid-wrappers/sendmail";
|
default = "/run/wrappers/bin/sendmail";
|
||||||
type = types.path;
|
type = types.path;
|
||||||
description = ''
|
description = ''
|
||||||
Sendmail-compatible binary to be used to send the messages.
|
Sendmail-compatible binary to be used to send the messages.
|
||||||
|
@ -30,7 +30,7 @@ let
|
|||||||
''
|
''
|
||||||
[ global ]
|
[ global ]
|
||||||
security = ${cfg.securityType}
|
security = ${cfg.securityType}
|
||||||
passwd program = /var/setuid-wrappers/passwd %u
|
passwd program = /run/wrappers/bin/passwd %u
|
||||||
pam password change = ${smbToString cfg.syncPasswordsByPam}
|
pam password change = ${smbToString cfg.syncPasswordsByPam}
|
||||||
invalid users = ${smbToString cfg.invalidUsers}
|
invalid users = ${smbToString cfg.invalidUsers}
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ in
|
|||||||
setgid = false;
|
setgid = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
security.setuidOwners = [ cfg.setuidWrapper ];
|
security.wrappers.gksign = cfg.setuidWrapper;
|
||||||
|
|
||||||
systemd.services.gale-galed = {
|
systemd.services.gale-galed = {
|
||||||
description = "Gale messaging daemon";
|
description = "Gale messaging daemon";
|
||||||
|
@ -18,7 +18,7 @@ let
|
|||||||
var_prefix = "${stateDir}"
|
var_prefix = "${stateDir}"
|
||||||
prayer_user = "${prayerUser}"
|
prayer_user = "${prayerUser}"
|
||||||
prayer_group = "${prayerGroup}"
|
prayer_group = "${prayerGroup}"
|
||||||
sendmail_path = "/var/setuid-wrappers/sendmail"
|
sendmail_path = "/run/wrappers/bin/sendmail"
|
||||||
|
|
||||||
use_http_port ${cfg.port}
|
use_http_port ${cfg.port}
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ in
|
|||||||
sendmail = mkOption {
|
sendmail = mkOption {
|
||||||
type = types.nullOr types.path;
|
type = types.nullOr types.path;
|
||||||
default = null;
|
default = null;
|
||||||
example = "/var/setuid-wrappers/sendmail";
|
example = "/run/wrappers/bin/sendmail";
|
||||||
description = "Use this sendmail compatible script to deliver alerts";
|
description = "Use this sendmail compatible script to deliver alerts";
|
||||||
};
|
};
|
||||||
smokeMailTemplate = mkOption {
|
smokeMailTemplate = mkOption {
|
||||||
@ -273,7 +273,10 @@ in
|
|||||||
message = "services.smokeping: sendmail and Mailhost cannot both be enabled.";
|
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 ];
|
environment.systemPackages = [ pkgs.fping ];
|
||||||
users.extraUsers = singleton {
|
users.extraUsers = singleton {
|
||||||
name = cfg.user;
|
name = cfg.user;
|
||||||
|
@ -42,13 +42,13 @@ in
|
|||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
security.setuidOwners = map (program: {
|
security.wrappers = map (program: {"${program}" = {
|
||||||
inherit program;
|
source = "${pkgs.atd}/bin/${program}";
|
||||||
owner = "atd";
|
owner = "atd";
|
||||||
group = "atd";
|
group = "atd";
|
||||||
setuid = true;
|
setuid = true;
|
||||||
setgid = true;
|
setgid = true;
|
||||||
}) [ "at" "atq" "atrm" "batch" ];
|
};}) [ "at" "atq" "atrm" "batch" ];
|
||||||
|
|
||||||
environment.systemPackages = [ at ];
|
environment.systemPackages = [ at ];
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ let
|
|||||||
cronNixosPkg = pkgs.cron.override {
|
cronNixosPkg = pkgs.cron.override {
|
||||||
# The mail.nix nixos module, if there is any local mail system enabled,
|
# The mail.nix nixos module, if there is any local mail system enabled,
|
||||||
# should have sendmail in this path.
|
# should have sendmail in this path.
|
||||||
sendmailPath = "/var/setuid-wrappers/sendmail";
|
sendmailPath = "/run/wrappers/bin/sendmail";
|
||||||
};
|
};
|
||||||
|
|
||||||
allFiles =
|
allFiles =
|
||||||
@ -61,7 +61,7 @@ in
|
|||||||
A list of Cron jobs to be appended to the system-wide
|
A list of Cron jobs to be appended to the system-wide
|
||||||
crontab. See the manual page for crontab for the expected
|
crontab. See the manual page for crontab for the expected
|
||||||
format. If you want to get the results mailed you must setuid
|
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
|
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
|
will is allowed to have its own crontab file. The /var/cron/cron.deny file
|
||||||
@ -92,13 +92,9 @@ in
|
|||||||
config = mkMerge [
|
config = mkMerge [
|
||||||
|
|
||||||
{ services.cron.enable = mkDefault (allFiles != []); }
|
{ services.cron.enable = mkDefault (allFiles != []); }
|
||||||
|
|
||||||
(mkIf (config.services.cron.enable) {
|
(mkIf (config.services.cron.enable) {
|
||||||
|
security.wrappers.crontab.source = "${pkgs.cronNixosPkg.out}/bin/crontab";
|
||||||
security.setuidPrograms = [ "crontab" ];
|
|
||||||
|
|
||||||
environment.systemPackages = [ cronNixosPkg ];
|
environment.systemPackages = [ cronNixosPkg ];
|
||||||
|
|
||||||
environment.etc.crontab =
|
environment.etc.crontab =
|
||||||
{ source = pkgs.runCommand "crontabs" { inherit allFiles; preferLocalBuild = true; }
|
{ source = pkgs.runCommand "crontabs" { inherit allFiles; preferLocalBuild = true; }
|
||||||
''
|
''
|
||||||
|
@ -96,7 +96,7 @@ in
|
|||||||
fcronallow = /etc/fcron.allow
|
fcronallow = /etc/fcron.allow
|
||||||
fcrondeny = /etc/fcron.deny
|
fcrondeny = /etc/fcron.deny
|
||||||
shell = /bin/sh
|
shell = /bin/sh
|
||||||
sendmail = /var/setuid-wrappers/sendmail
|
sendmail = /run/wrappers/bin/sendmail
|
||||||
editor = /run/current-system/sw/bin/vi
|
editor = /run/current-system/sw/bin/vi
|
||||||
'';
|
'';
|
||||||
target = "fcron.conf";
|
target = "fcron.conf";
|
||||||
@ -106,8 +106,7 @@ in
|
|||||||
|
|
||||||
environment.systemPackages = [ pkgs.fcron ];
|
environment.systemPackages = [ pkgs.fcron ];
|
||||||
|
|
||||||
security.setuidPrograms = [ "fcrontab" ];
|
security.wrappers.fcrontab.source = "${pkgs.fcron.out}/bin/fcrontab";
|
||||||
|
|
||||||
systemd.services.fcron = {
|
systemd.services.fcron = {
|
||||||
description = "fcron daemon";
|
description = "fcron daemon";
|
||||||
after = [ "local-fs.target" ];
|
after = [ "local-fs.target" ];
|
||||||
|
@ -104,8 +104,7 @@ in
|
|||||||
|
|
||||||
systemd.packages = [ pkgs.dbus.daemon ];
|
systemd.packages = [ pkgs.dbus.daemon ];
|
||||||
|
|
||||||
security.setuidOwners = singleton
|
security.wrappers.dbus-daemon-launch-helper = {
|
||||||
{ program = "dbus-daemon-launch-helper";
|
|
||||||
source = "${pkgs.dbus.daemon}/libexec/dbus-daemon-launch-helper";
|
source = "${pkgs.dbus.daemon}/libexec/dbus-daemon-launch-helper";
|
||||||
owner = "root";
|
owner = "root";
|
||||||
group = "messagebus";
|
group = "messagebus";
|
||||||
|
@ -62,7 +62,7 @@ in
|
|||||||
'';
|
'';
|
||||||
}];
|
}];
|
||||||
|
|
||||||
security.setuidPrograms = [ "e_freqset" ];
|
security.wrappers.e_freqset.source = "${e.enlightenment.out}/bin/e_freqset";
|
||||||
|
|
||||||
environment.etc = singleton
|
environment.etc = singleton
|
||||||
{ source = "${pkgs.xkeyboard_config}/etc/X11/xkb";
|
{ source = "${pkgs.xkeyboard_config}/etc/X11/xkb";
|
||||||
|
@ -61,24 +61,13 @@ in
|
|||||||
''}
|
''}
|
||||||
|
|
||||||
exec "${kde5.startkde}"
|
exec "${kde5.startkde}"
|
||||||
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
security.setuidOwners = [
|
security.wrappers = {
|
||||||
{
|
kcheckpass.source = "${kde5.plasma-workspace.out}/lib/libexec/kcheckpass";
|
||||||
program = "kcheckpass";
|
"start_kdeinit".source = "${kde5.kinit.out}/lib/libexec/kf5/start_kdeinit";
|
||||||
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;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
environment.systemPackages =
|
environment.systemPackages =
|
||||||
[
|
[
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{ config, lib, pkgs, utils, ... }:
|
{ config, lib, pkgs, utils, stdenv, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
with utils;
|
with utils;
|
||||||
@ -933,7 +933,22 @@ in
|
|||||||
(i: flip map [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${i.name}.proxy_arp" true))
|
(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
|
# Set the host and domain names in the activation script. Don't
|
||||||
# clear it if it's not configured in the NixOS configuration,
|
# clear it if it's not configured in the NixOS configuration,
|
||||||
|
@ -68,14 +68,13 @@ in
|
|||||||
boot.extraModulePackages = [ kernelModules ];
|
boot.extraModulePackages = [ kernelModules ];
|
||||||
environment.systemPackages = [ virtualbox ];
|
environment.systemPackages = [ virtualbox ];
|
||||||
|
|
||||||
security.setuidOwners = let
|
security.wrappers = let
|
||||||
mkSuid = program: {
|
mkSuid = program: {"${program}" = {
|
||||||
inherit program;
|
|
||||||
source = "${virtualbox}/libexec/virtualbox/${program}";
|
source = "${virtualbox}/libexec/virtualbox/${program}";
|
||||||
owner = "root";
|
owner = "root";
|
||||||
group = "vboxusers";
|
group = "vboxusers";
|
||||||
setuid = true;
|
setuid = true;
|
||||||
};
|
};};
|
||||||
in mkIf cfg.enableHardening (map mkSuid [
|
in mkIf cfg.enableHardening (map mkSuid [
|
||||||
"VBoxHeadless"
|
"VBoxHeadless"
|
||||||
"VBoxNetAdpCtl"
|
"VBoxNetAdpCtl"
|
||||||
@ -99,7 +98,7 @@ in
|
|||||||
SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh --remove $major $minor"
|
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 {
|
} (mkIf cfg.addNetworkInterface {
|
||||||
systemd.services."vboxnet0" =
|
systemd.services."vboxnet0" =
|
||||||
{ description = "VirtualBox vboxnet0 Interface";
|
{ description = "VirtualBox vboxnet0 Interface";
|
||||||
|
@ -14,7 +14,7 @@ import ./make-test.nix ({ pkgs, ...} : {
|
|||||||
mailHost = "127.0.0.2";
|
mailHost = "127.0.0.2";
|
||||||
probeConfig = ''
|
probeConfig = ''
|
||||||
+ FPing
|
+ FPing
|
||||||
binary = /var/setuid-wrappers/fping
|
binary = /run/wrappers/bin/fping
|
||||||
offset = 0%
|
offset = 0%
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{ fetchurl, stdenv, glib, xorg, cairo, gtk2, pango, makeWrapper, openssl, bzip2,
|
{ 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}:
|
gksuSupport ? false, gksu}:
|
||||||
|
|
||||||
assert stdenv.system == "i686-linux" || stdenv.system == "x86_64-linux";
|
assert stdenv.system == "i686-linux" || stdenv.system == "x86_64-linux";
|
||||||
|
@ -83,9 +83,9 @@ in stdenv.mkDerivation {
|
|||||||
ed -v -s "$out/bin/chromium" << EOF
|
ed -v -s "$out/bin/chromium" << EOF
|
||||||
2i
|
2i
|
||||||
|
|
||||||
if [ -x "/var/setuid-wrappers/${sandboxExecutableName}" ]
|
if [ -x "/run/wrappers/bin/${sandboxExecutableName}" ]
|
||||||
then
|
then
|
||||||
export CHROME_DEVEL_SANDBOX="/var/setuid-wrappers/${sandboxExecutableName}"
|
export CHROME_DEVEL_SANDBOX="/run/wrappers/bin/${sandboxExecutableName}"
|
||||||
else
|
else
|
||||||
export CHROME_DEVEL_SANDBOX="$sandbox/bin/${sandboxExecutableName}"
|
export CHROME_DEVEL_SANDBOX="$sandbox/bin/${sandboxExecutableName}"
|
||||||
fi
|
fi
|
||||||
|
@ -26,7 +26,7 @@ index 50e8ad8..eec0ed2 100644
|
|||||||
+ is_nixos=no
|
+ is_nixos=no
|
||||||
+fi
|
+fi
|
||||||
+
|
+
|
||||||
+if [ -u /var/setuid-wrappers/gksign ]; then
|
+if [ -u /run/wrappers/bin/gksign ]; then
|
||||||
+ cat <<EOM
|
+ cat <<EOM
|
||||||
+
|
+
|
||||||
+Gale appears to have already been set up via the NixOS module system (check
|
+Gale appears to have already been set up via the NixOS module system (check
|
||||||
|
@ -4,7 +4,7 @@ Date: Thu, 26 Nov 2015 21:03:35 +0100
|
|||||||
Subject: [PATCH] Lookup dumpcap in PATH
|
Subject: [PATCH] Lookup dumpcap in PATH
|
||||||
|
|
||||||
NixOS patch: Look for dumpcap in PATH first, because there may be a
|
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.
|
non-setuid dumpcap binary.
|
||||||
|
|
||||||
Also change execv() to execvp() because we've set argv[0] to "dumpcap"
|
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);
|
- exename = g_strdup_printf("%s/dumpcap", progfile_dir);
|
||||||
+ /*
|
+ /*
|
||||||
+ * NixOS patch: Look for dumpcap in PATH first, because there may be a
|
+ * 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.
|
+ * non-setuid dumpcap binary.
|
||||||
+ */
|
+ */
|
||||||
+ if (system("command -v dumpcap >/dev/null") == 0) {
|
+ if (system("command -v dumpcap >/dev/null") == 0) {
|
||||||
|
@ -11,7 +11,7 @@ index a9d8ac4..85f13f5 100644
|
|||||||
- # # arguments: '-i -t'
|
- # # arguments: '-i -t'
|
||||||
- # # }
|
- # # }
|
||||||
+ config.action_mailer.sendmail_settings = {
|
+ config.action_mailer.sendmail_settings = {
|
||||||
+ location: '/var/setuid-wrappers/sendmail',
|
+ location: '/run/wrappers/bin/sendmail',
|
||||||
+ arguments: '-i -t'
|
+ arguments: '-i -t'
|
||||||
+ }
|
+ }
|
||||||
config.action_mailer.perform_deliveries = true
|
config.action_mailer.perform_deliveries = true
|
||||||
|
@ -96,7 +96,7 @@ index 95dc9a7..39170bc 100644
|
|||||||
/* get the path to the executable */
|
/* get the path to the executable */
|
||||||
char szPath[RTPATH_MAX];
|
char szPath[RTPATH_MAX];
|
||||||
- RTPathAppPrivateArch(szPath, sizeof(szPath) - 1);
|
- 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);
|
size_t cchBufLeft = strlen(szPath);
|
||||||
szPath[cchBufLeft++] = RTPATH_DELIMITER;
|
szPath[cchBufLeft++] = RTPATH_DELIMITER;
|
||||||
szPath[cchBufLeft] = 0;
|
szPath[cchBufLeft] = 0;
|
||||||
@ -154,7 +154,7 @@ index be2ad8f..7ddf105 100644
|
|||||||
|
|
||||||
+RTDECL(int) RTPathSuidDir(char *pszPath, size_t cchPath)
|
+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
|
+ * will cut off everything after the rightmost / as this function is analogous
|
||||||
+ * to RTProcGetExecutablePath().
|
+ * to RTProcGetExecutablePath().
|
||||||
+ */
|
+ */
|
||||||
+#define SUIDDIR "/var/setuid-wrappers/"
|
+#define SUIDDIR "/run/wrappers/bin/"
|
||||||
+
|
+
|
||||||
+RTR3DECL(char *) RTProcGetSuidPath(char *pszExecPath, size_t cbExecPath)
|
+RTR3DECL(char *) RTProcGetSuidPath(char *pszExecPath, size_t cbExecPath)
|
||||||
+{
|
+{
|
||||||
|
@ -51,7 +51,7 @@ let
|
|||||||
export PS1='${name}-chrootenv:\u@\h:\w\$ '
|
export PS1='${name}-chrootenv:\u@\h:\w\$ '
|
||||||
export LOCALE_ARCHIVE='/usr/lib/locale/locale-archive'
|
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 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
|
export PKG_CONFIG_PATH=/usr/lib/pkgconfig
|
||||||
|
|
||||||
# Force compilers to look in default search paths
|
# Force compilers to look in default search paths
|
||||||
|
@ -42,13 +42,13 @@ stdenv.mkDerivation rec {
|
|||||||
# this is a hack and without this cpufreq module is not working. does the following:
|
# this is a hack and without this cpufreq module is not working. does the following:
|
||||||
# 1. moves the "freqset" binary to "e_freqset",
|
# 1. moves the "freqset" binary to "e_freqset",
|
||||||
# 2. linkes "e_freqset" to enlightenment/bin so that,
|
# 2. linkes "e_freqset" to enlightenment/bin so that,
|
||||||
# 3. setuidPrograms detects it and makes appropriate stuff to /var/setuid-wrappers/e_freqset,
|
# 3. wrappers.setuid detects it and places wrappers in /run/wrappers/bin/e_freqset,
|
||||||
# 4. and finaly, linkes /var/setuid-wrappers/e_freqset to original destination where enlightenment wants it
|
# 4. and finally, links /run/wrappers/bin/e_freqset to original destination where enlightenment wants it
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
export CPUFREQ_DIRPATH=`readlink -f $out/lib/enlightenment/modules/cpufreq/linux-gnu-*`;
|
export CPUFREQ_DIRPATH=`readlink -f $out/lib/enlightenment/modules/cpufreq/linux-gnu-*`;
|
||||||
mv $CPUFREQ_DIRPATH/freqset $CPUFREQ_DIRPATH/e_freqset
|
mv $CPUFREQ_DIRPATH/freqset $CPUFREQ_DIRPATH/e_freqset
|
||||||
ln -sv $CPUFREQ_DIRPATH/e_freqset $out/bin/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; {
|
meta = with stdenv.lib; {
|
||||||
|
@ -7,7 +7,7 @@ Index: kinit-5.24.0/src/start_kdeinit/start_kdeinit_wrapper.c
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
-#define EXECUTE CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/start_kdeinit"
|
-#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
|
#if KDEINIT_OOM_PROTECT
|
||||||
|
|
||||||
|
@ -57,8 +57,8 @@ stdenv.mkDerivation rec {
|
|||||||
|
|
||||||
# Fix some binary paths
|
# 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/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|/usr/bin/sudo|/run/wrappers/bin/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|/bin/su\([^d]\)|/run/wrappers/bin/su\1|g' libgksu/libgksu.c
|
||||||
|
|
||||||
touch NEWS README
|
touch NEWS README
|
||||||
'';
|
'';
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
let
|
let
|
||||||
|
|
||||||
system = "/var/run/current-system/sw";
|
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 = {
|
foolVars = {
|
||||||
SYSCONF = "/etc";
|
SYSCONF = "/etc";
|
||||||
|
@ -94,7 +94,7 @@ in stdenv.mkDerivation rec {
|
|||||||
unitydir="$out/opt/Unity/Editor"
|
unitydir="$out/opt/Unity/Editor"
|
||||||
mkdir -p $unitydir
|
mkdir -p $unitydir
|
||||||
mv Editor/* $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
|
mkdir -p $out/share/applications
|
||||||
sed "/^Exec=/c\Exec=$out/bin/unity-editor" \
|
sed "/^Exec=/c\Exec=$out/bin/unity-editor" \
|
||||||
|
@ -28,7 +28,7 @@ stdenv.mkDerivation rec {
|
|||||||
# Ensure that FUSE calls the setuid wrapper, not
|
# Ensure that FUSE calls the setuid wrapper, not
|
||||||
# $out/bin/fusermount. It falls back to calling fusermount in
|
# $out/bin/fusermount. It falls back to calling fusermount in
|
||||||
# $PATH, so it should also work on non-NixOS systems.
|
# $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@/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
|
sed -e 's@CONFIG_RPATH=/usr/share/gettext/config.rpath@CONFIG_RPATH=${gettext}/share/gettext/config.rpath@' -i makeconf.sh
|
||||||
|
@ -31,7 +31,7 @@ stdenv.mkDerivation rec {
|
|||||||
preConfigure = ''
|
preConfigure = ''
|
||||||
sed -e 's@/lib/udev@''${out}/lib/udev@' \
|
sed -e 's@/lib/udev@''${out}/lib/udev@' \
|
||||||
-e 's@ -Werror @ @' \
|
-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 = {
|
meta = {
|
||||||
|
@ -31,7 +31,7 @@ stdenv.mkDerivation rec {
|
|||||||
preConfigure = ''
|
preConfigure = ''
|
||||||
sed -e 's@/lib/udev@''${out}/lib/udev@' \
|
sed -e 's@/lib/udev@''${out}/lib/udev@' \
|
||||||
-e 's@ -Werror @ @' \
|
-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 = {
|
meta = {
|
||||||
|
@ -34,7 +34,7 @@ stdenv.mkDerivation rec {
|
|||||||
|
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
mv -v $out/sbin/unix_chkpwd{,.orig}
|
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
|
rm -rf $out/etc
|
||||||
mkdir -p $modules/lib
|
mkdir -p $modules/lib
|
||||||
|
@ -36,7 +36,7 @@ stdenv.mkDerivation rec {
|
|||||||
--enable-last
|
--enable-last
|
||||||
--enable-mesg
|
--enable-mesg
|
||||||
--disable-use-tty-group
|
--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 ncurses == null then "--without-ncurses" else ""}
|
||||||
${if systemd == null then "" else ''
|
${if systemd == null then "" else ''
|
||||||
--with-systemd
|
--with-systemd
|
||||||
|
@ -30,7 +30,7 @@ buildGoPackage rec {
|
|||||||
-e 's|/bin/chown|${coreutils}/bin/chown|' \
|
-e 's|/bin/chown|${coreutils}/bin/chown|' \
|
||||||
-e 's|/bin/date|${coreutils}/bin/date|' \
|
-e 's|/bin/date|${coreutils}/bin/date|' \
|
||||||
-e 's|/sbin/poweroff|${systemd}/sbin/poweroff|' \
|
-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|'
|
-e 's|/sbin/cryptsetup|${cryptsetup}/bin/cryptsetup|'
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
stdenv.mkDerivation rec {
|
||||||
name = "petidomo-4.3";
|
name = "petidomo-4.3";
|
||||||
|
@ -16,8 +16,8 @@ stdenv.mkDerivation rec {
|
|||||||
# configured on the build machine).
|
# configured on the build machine).
|
||||||
preConfigure= "
|
preConfigure= "
|
||||||
configureFlagsArray=(
|
configureFlagsArray=(
|
||||||
--with-ping-command='/var/setuid-wrappers/ping -n -U -w %d -c %d %s'
|
--with-ping-command='/run/wrappers/bin/ping -n -U -w %d -c %d %s'
|
||||||
--with-ping6-command='/var/setuid-wrappers/ping6 -n -U -w %d -c %d %s'
|
--with-ping6-command='/run/wrappers/bin/ping6 -n -U -w %d -c %d %s'
|
||||||
)
|
)
|
||||||
";
|
";
|
||||||
|
|
||||||
|
@ -20,10 +20,10 @@ stdenv.mkDerivation rec {
|
|||||||
configureFlags="--mandir=$out/share/man"
|
configureFlags="--mandir=$out/share/man"
|
||||||
|
|
||||||
substituteInPlace x11vnc/unixpw.c \
|
substituteInPlace x11vnc/unixpw.c \
|
||||||
--replace '"/bin/su"' '"/var/setuid-wrappers/su"' \
|
--replace '"/bin/su"' '"/run/wrappers/bin/su"' \
|
||||||
--replace '"/bin/true"' '"${coreutils}/bin/true"'
|
--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 = {
|
meta = {
|
||||||
|
@ -31,7 +31,7 @@ python2Packages.buildPythonApplication rec {
|
|||||||
buildInputs = [ dialog ] ++ (with python2Packages; [ nose mock gnureadline ]);
|
buildInputs = [ dialog ] ++ (with python2Packages; [ nose mock gnureadline ]);
|
||||||
|
|
||||||
patchPhase = ''
|
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"
|
substituteInPlace certbot/util.py --replace "sw_vers" "/usr/bin/sw_vers"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
, FileDesktopEntry, libxslt, docbook_xsl, makeWrapper
|
, FileDesktopEntry, libxslt, docbook_xsl, makeWrapper
|
||||||
, python3Packages
|
, python3Packages
|
||||||
, perlPackages, curl, gnupg, diffutils
|
, perlPackages, curl, gnupg, diffutils
|
||||||
, sendmailPath ? "/var/setuid-wrappers/sendmail"
|
, sendmailPath ? "/run/wrappers/bin/sendmail"
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
@ -11,7 +11,7 @@ stdenv.mkDerivation rec {
|
|||||||
};
|
};
|
||||||
|
|
||||||
# TODO: replace wrapperDir below with from <nixos> config.security.wrapperDir;
|
# TODO: replace wrapperDir below with from <nixos> config.security.wrapperDir;
|
||||||
wrapperDir = "/var/setuid-wrappers";
|
wrapperDir = "/run/wrappers/bin";
|
||||||
|
|
||||||
postPatch = ''
|
postPatch = ''
|
||||||
FILES="$(grep -r '/bin/sh' src/utils -l; find src -name \*.c)"
|
FILES="$(grep -r '/bin/sh' src/utils -l; find src -name \*.c)"
|
||||||
|
@ -18,7 +18,7 @@ stdenv.mkDerivation rec {
|
|||||||
|
|
||||||
buildInputs = [ makeWrapper ];
|
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 = ''
|
installPhase = ''
|
||||||
mkdir -p $out/bin $out/libexec
|
mkdir -p $out/bin $out/libexec
|
||||||
cp $src $out/libexec/ecryptfs-helper.py
|
cp $src $out/libexec/ecryptfs-helper.py
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{ stdenv, fetchurl, coreutils, pam, groff
|
{ stdenv, fetchurl, coreutils, pam, groff
|
||||||
, sendmailPath ? "/var/setuid-wrappers/sendmail"
|
, sendmailPath ? "/run/wrappers/bin/sendmail"
|
||||||
, withInsults ? false
|
, withInsults ? false
|
||||||
}:
|
}:
|
||||||
|
|
||||||
|
@ -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 {
|
stdenv.mkDerivation {
|
||||||
name = "at-3.1.16";
|
name = "at-3.1.16";
|
||||||
|
@ -23,7 +23,7 @@ stdenv.mkDerivation {
|
|||||||
#define _PATH_SENDMAIL "${sendmailPath}"
|
#define _PATH_SENDMAIL "${sendmailPath}"
|
||||||
|
|
||||||
#undef _PATH_DEFPATH
|
#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__
|
__EOT__
|
||||||
|
|
||||||
# Implicit saved uids do not work here due to way NixOS uses setuid wrappers
|
# Implicit saved uids do not work here due to way NixOS uses setuid wrappers
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{stdenv, fetchurl,
|
{stdenv, fetchurl,
|
||||||
sendmailPath ? "/var/setuid-wrappers/sendmail" }:
|
sendmailPath ? "/run/wrappers/bin/sendmail" }:
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user