From dee90b2c251aebb4557f1d0fb55c40cf67e85381 Mon Sep 17 00:00:00 2001 From: Nikolay Amiantov Date: Wed, 4 Feb 2015 01:28:32 +0300 Subject: [PATCH] util-linux: fix unshare -r on linux >=3.19 (close #6130) --- pkgs/os-specific/linux/util-linux/default.nix | 4 +- .../unshare-fix-map-root-user.patch | 66 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 pkgs/os-specific/linux/util-linux/unshare-fix-map-root-user.patch diff --git a/pkgs/os-specific/linux/util-linux/default.nix b/pkgs/os-specific/linux/util-linux/default.nix index 8842e76362a..81eeee68fba 100644 --- a/pkgs/os-specific/linux/util-linux/default.nix +++ b/pkgs/os-specific/linux/util-linux/default.nix @@ -8,7 +8,9 @@ stdenv.mkDerivation rec { sha256 = "e0457f715b73f4a349e1acb08cb410bf0edc9a74a3f75c357070f31f70e33cd6"; }; - patches = [ ./rtcwake-search-PATH-for-shutdown.patch ]; + patches = [ ./rtcwake-search-PATH-for-shutdown.patch + ./unshare-fix-map-root-user.patch + ]; #FIXME: make it also work on non-nixos? postPatch = '' diff --git a/pkgs/os-specific/linux/util-linux/unshare-fix-map-root-user.patch b/pkgs/os-specific/linux/util-linux/unshare-fix-map-root-user.patch new file mode 100644 index 00000000000..1d1531e110c --- /dev/null +++ b/pkgs/os-specific/linux/util-linux/unshare-fix-map-root-user.patch @@ -0,0 +1,66 @@ +In rare cases droping groups with setgroups(0, NULL) is an operation +that can grant a user additional privileges. User namespaces were +allwoing that operation to unprivileged users and that had to be +fixed. + +Update unshare --map-root-user to disable the setgroups operation +before setting the gid_map. + +This is needed as after the security fix gid_map is restricted to +privileged users unless setgroups has been disabled. + +Signed-off-by: "Eric W. Biederman" +--- + include/pathnames.h | 1 + + sys-utils/unshare.c | 19 +++++++++++++++++++ + 2 files changed, 20 insertions(+) + +diff --git a/include/pathnames.h b/include/pathnames.h +index 1cc4e15e6e4f..1c53e4554268 100644 +--- a/include/pathnames.h ++++ b/include/pathnames.h +@@ -92,6 +92,7 @@ + + #define _PATH_PROC_UIDMAP "/proc/self/uid_map" + #define _PATH_PROC_GIDMAP "/proc/self/gid_map" ++#define _PATH_PROC_SETGROUPS "/proc/self/setgroups" + + #define _PATH_PROC_ATTR_CURRENT "/proc/self/attr/current" + #define _PATH_PROC_ATTR_EXEC "/proc/self/attr/exec" +diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c +index 95e4afbd055e..d409a7c936b6 100644 +--- a/sys-utils/unshare.c ++++ b/sys-utils/unshare.c +@@ -39,6 +39,24 @@ + #include "pathnames.h" + #include "all-io.h" + ++static void disable_setgroups(void) ++{ ++ const char *file = _PATH_PROC_SETGROUPS; ++ const char *deny = "deny"; ++ int fd; ++ ++ fd = open(file, O_WRONLY); ++ if (fd < 0) { ++ if (errno == ENOENT) ++ return; ++ err(EXIT_FAILURE, _("cannot open %s"), file); ++ } ++ ++ if (write_all(fd, deny, strlen(deny))) ++ err(EXIT_FAILURE, _("write failed %s"), file); ++ close(fd); ++} ++ + static void map_id(const char *file, uint32_t from, uint32_t to) + { + char *buf; +@@ -178,6 +196,7 @@ int main(int argc, char *argv[]) + } + + if (maproot) { ++ disable_setgroups(); + map_id(_PATH_PROC_UIDMAP, 0, real_euid); + map_id(_PATH_PROC_GIDMAP, 0, real_egid); + }