diff --git a/debian/patches/0001-lxc.service-start-after-a-potential-syslog.service.patch b/debian/patches/0001-lxc.service-start-after-a-potential-syslog.service.patch index 131c213..05f55ae 100644 --- a/debian/patches/0001-lxc.service-start-after-a-potential-syslog.service.patch +++ b/debian/patches/0001-lxc.service-start-after-a-potential-syslog.service.patch @@ -1,7 +1,7 @@ From 10bc10054434f20870f812bb710eef5b5e22040b Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Fri, 10 Feb 2017 09:13:40 +0100 -Subject: [PATCH 1/8] lxc.service: start after a potential syslog.service +Subject: [PATCH 1/9] lxc.service: start after a potential syslog.service Signed-off-by: Wolfgang Bumiller --- diff --git a/debian/patches/0002-jessie-systemd-remove-Delegate-flag-to-silence-warni.patch b/debian/patches/0002-jessie-systemd-remove-Delegate-flag-to-silence-warni.patch index 8d22d8e..a91aa4d 100644 --- a/debian/patches/0002-jessie-systemd-remove-Delegate-flag-to-silence-warni.patch +++ b/debian/patches/0002-jessie-systemd-remove-Delegate-flag-to-silence-warni.patch @@ -1,7 +1,7 @@ From e68a4291abec1c140fffbc8c954ff9596b17aad4 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Fri, 10 Feb 2017 09:14:55 +0100 -Subject: [PATCH 2/8] jessie/systemd: remove Delegate flag to silence warnings +Subject: [PATCH 2/9] jessie/systemd: remove Delegate flag to silence warnings Signed-off-by: Wolfgang Bumiller --- diff --git a/debian/patches/0003-pve-run-lxcnetaddbr-when-instantiating-veths.patch b/debian/patches/0003-pve-run-lxcnetaddbr-when-instantiating-veths.patch index 619047a..c6b6e92 100644 --- a/debian/patches/0003-pve-run-lxcnetaddbr-when-instantiating-veths.patch +++ b/debian/patches/0003-pve-run-lxcnetaddbr-when-instantiating-veths.patch @@ -1,7 +1,7 @@ From 6b3de84e0654c3b0b13166d63af9961a3a757c6e Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Fri, 10 Feb 2017 09:15:37 +0100 -Subject: [PATCH 3/8] pve: run lxcnetaddbr when instantiating veths +Subject: [PATCH 3/9] pve: run lxcnetaddbr when instantiating veths FIXME: Why aren't we using regular up-scripts? diff --git a/debian/patches/0004-deny-rw-mounting-of-sys-and-proc.patch b/debian/patches/0004-deny-rw-mounting-of-sys-and-proc.patch index 2cdfd36..eb271c8 100644 --- a/debian/patches/0004-deny-rw-mounting-of-sys-and-proc.patch +++ b/debian/patches/0004-deny-rw-mounting-of-sys-and-proc.patch @@ -1,7 +1,7 @@ From e7d6b0d2384070f2c34a46aaa20250ce31f96c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= Date: Wed, 9 Nov 2016 09:14:26 +0100 -Subject: [PATCH 4/8] deny rw mounting of /sys and /proc +Subject: [PATCH 4/9] deny rw mounting of /sys and /proc this would allow root in a privileged container to change the permissions of /sys on the host, which could lock out diff --git a/debian/patches/0005-separate-the-limiting-from-the-namespaced-cgroup-roo.patch b/debian/patches/0005-separate-the-limiting-from-the-namespaced-cgroup-roo.patch index 163da92..51402b5 100644 --- a/debian/patches/0005-separate-the-limiting-from-the-namespaced-cgroup-roo.patch +++ b/debian/patches/0005-separate-the-limiting-from-the-namespaced-cgroup-roo.patch @@ -1,7 +1,7 @@ From 6adbaea0d07553932f4cd78b5530cd5291c3b41f Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Tue, 15 Nov 2016 09:20:24 +0100 -Subject: [PATCH 5/8] separate the limiting from the namespaced cgroup root +Subject: [PATCH 5/9] separate the limiting from the namespaced cgroup root When cgroup namespaces are enabled a privileged container with mixed cgroups has full write access to its own root diff --git a/debian/patches/0006-start-initutils-make-cgroupns-separation-level-confi.patch b/debian/patches/0006-start-initutils-make-cgroupns-separation-level-confi.patch index c8c087a..ca114da 100644 --- a/debian/patches/0006-start-initutils-make-cgroupns-separation-level-confi.patch +++ b/debian/patches/0006-start-initutils-make-cgroupns-separation-level-confi.patch @@ -1,7 +1,7 @@ From af72260927efd412210ec85842e1ef70ccc0c5e8 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Wed, 16 Nov 2016 09:53:42 +0100 -Subject: [PATCH 6/8] start/initutils: make cgroupns separation level +Subject: [PATCH 6/9] start/initutils: make cgroupns separation level configurable Adds a new global config variable `lxc.cgroup.separate` diff --git a/debian/patches/0007-rename-cgroup-namespace-directory-to-ns.patch b/debian/patches/0007-rename-cgroup-namespace-directory-to-ns.patch index 6ed92de..0421cb5 100644 --- a/debian/patches/0007-rename-cgroup-namespace-directory-to-ns.patch +++ b/debian/patches/0007-rename-cgroup-namespace-directory-to-ns.patch @@ -1,7 +1,7 @@ From 3790507952f3cda5c6dd9bb6f87c80d9b0ddadf7 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Fri, 23 Dec 2016 15:57:24 +0100 -Subject: [PATCH 7/8] rename cgroup namespace directory to ns +Subject: [PATCH 7/9] rename cgroup namespace directory to ns Signed-off-by: Wolfgang Bumiller --- diff --git a/debian/patches/0008-possibility-to-run-lxc-monitord-as-a-regular-daemon.patch b/debian/patches/0008-possibility-to-run-lxc-monitord-as-a-regular-daemon.patch index ea7c9bc..2119d45 100644 --- a/debian/patches/0008-possibility-to-run-lxc-monitord-as-a-regular-daemon.patch +++ b/debian/patches/0008-possibility-to-run-lxc-monitord-as-a-regular-daemon.patch @@ -1,7 +1,7 @@ -From 1bdcf98811093349ca856dac4beb3f5bd0dd501b Mon Sep 17 00:00:00 2001 +From 24af6aaf126f63229b3f9289b7dba58b3f07e847 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Fri, 10 Feb 2017 10:23:36 +0100 -Subject: [PATCH 8/8] possibility to run lxc-monitord as a regular daemon +Subject: [PATCH 8/9] possibility to run lxc-monitord as a regular daemon This includes an lxc-monitord.service, required by lxc@.service which is now of Type=forking. @@ -78,7 +78,7 @@ index 0000000..4063516 +[Install] +WantedBy=multi-user.target diff --git a/config/init/systemd/lxc@.service.in b/config/init/systemd/lxc@.service.in -index 6b8b5ff..ffb9136 100644 +index 6b8b5ff..c35526b 100644 --- a/config/init/systemd/lxc@.service.in +++ b/config/init/systemd/lxc@.service.in @@ -1,16 +1,17 @@ diff --git a/debian/patches/0009-CVE-2017-5985-Ensure-target-netns-is-caller-owned.patch b/debian/patches/0009-CVE-2017-5985-Ensure-target-netns-is-caller-owned.patch new file mode 100644 index 0000000..7147cba --- /dev/null +++ b/debian/patches/0009-CVE-2017-5985-Ensure-target-netns-is-caller-owned.patch @@ -0,0 +1,188 @@ +From 8095074e1aa2b308d8134638999a0ffe25e12347 Mon Sep 17 00:00:00 2001 +From: Christian Brauner +Date: Sat, 28 Jan 2017 13:02:34 +0100 +Subject: [PATCH 9/9] CVE-2017-5985: Ensure target netns is caller-owned + +Before this commit, lxc-user-nic could potentially have been tricked into +operating on a network namespace over which the caller did not hold privilege. + +This commit ensures that the caller is privileged over the network namespace by +temporarily dropping privilege. + +Launchpad: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1654676 +Reported-by: Jann Horn +Signed-off-by: Christian Brauner +--- + src/lxc/lxc_user_nic.c | 119 ++++++++++++++++++++++++++++++++++++------------- + 1 file changed, 87 insertions(+), 32 deletions(-) + +diff --git a/src/lxc/lxc_user_nic.c b/src/lxc/lxc_user_nic.c +index 409a53a..96dc398 100644 +--- a/src/lxc/lxc_user_nic.c ++++ b/src/lxc/lxc_user_nic.c +@@ -50,6 +50,14 @@ + #include "utils.h" + #include "network.h" + ++#define usernic_debug_stream(stream, format, ...) \ ++ do { \ ++ fprintf(stream, "%s: %d: %s: " format, __FILE__, __LINE__, \ ++ __func__, __VA_ARGS__); \ ++ } while (false) ++ ++#define usernic_error(format, ...) usernic_debug_stream(stderr, format, __VA_ARGS__) ++ + static void usage(char *me, bool fail) + { + fprintf(stderr, "Usage: %s lxcpath name pid type bridge nicname\n", me); +@@ -670,68 +678,115 @@ again: + } + + #define VETH_DEF_NAME "eth%d" +- + static int rename_in_ns(int pid, char *oldname, char **newnamep) + { +- int fd = -1, ofd = -1, ret, ifindex = -1; ++ uid_t ruid, suid, euid; ++ int fret = -1; ++ int fd = -1, ifindex = -1, ofd = -1, ret; + bool grab_newname = false; + + ofd = lxc_preserve_ns(getpid(), "net"); + if (ofd < 0) { +- fprintf(stderr, "Failed opening network namespace path for '%d'.", getpid()); +- return -1; ++ usernic_error("Failed opening network namespace path for '%d'.", getpid()); ++ return fret; + } + + fd = lxc_preserve_ns(pid, "net"); + if (fd < 0) { +- fprintf(stderr, "Failed opening network namespace path for '%d'.", pid); +- return -1; ++ usernic_error("Failed opening network namespace path for '%d'.", pid); ++ goto do_partial_cleanup; ++ } ++ ++ ret = getresuid(&ruid, &euid, &suid); ++ if (ret < 0) { ++ usernic_error("Failed to retrieve real, effective, and saved " ++ "user IDs: %s\n", ++ strerror(errno)); ++ goto do_partial_cleanup; ++ } ++ ++ ret = setns(fd, CLONE_NEWNET); ++ close(fd); ++ fd = -1; ++ if (ret < 0) { ++ usernic_error("Failed to setns() to the network namespace of " ++ "the container with PID %d: %s.\n", ++ pid, strerror(errno)); ++ goto do_partial_cleanup; + } + +- if (setns(fd, 0) < 0) { +- fprintf(stderr, "setns to container network namespace\n"); +- goto out_err; ++ ret = setresuid(ruid, ruid, 0); ++ if (ret < 0) { ++ usernic_error("Failed to drop privilege by setting effective " ++ "user id and real user id to %d, and saved user " ++ "ID to 0: %s.\n", ++ ruid, strerror(errno)); ++ // COMMENT(brauner): It's ok to jump to do_full_cleanup here ++ // since setresuid() will succeed when trying to set real, ++ // effective, and saved to values they currently have. ++ goto do_full_cleanup; + } +- close(fd); fd = -1; ++ + if (!*newnamep) { + grab_newname = true; + *newnamep = VETH_DEF_NAME; +- if (!(ifindex = if_nametoindex(oldname))) { +- fprintf(stderr, "failed to get netdev index\n"); +- goto out_err; ++ ++ ifindex = if_nametoindex(oldname); ++ if (!ifindex) { ++ usernic_error("Failed to get netdev index: %s.\n", strerror(errno)); ++ goto do_full_cleanup; + } + } +- if ((ret = lxc_netdev_rename_by_name(oldname, *newnamep)) < 0) { +- fprintf(stderr, "Error %d renaming netdev %s to %s in container\n", ret, oldname, *newnamep); +- goto out_err; ++ ++ ret = lxc_netdev_rename_by_name(oldname, *newnamep); ++ if (ret < 0) { ++ usernic_error("Error %d renaming netdev %s to %s in container.\n", ret, oldname, *newnamep); ++ goto do_full_cleanup; + } ++ + if (grab_newname) { +- char ifname[IFNAMSIZ], *namep = ifname; ++ char ifname[IFNAMSIZ]; ++ char *namep = ifname; ++ + if (!if_indextoname(ifindex, namep)) { +- fprintf(stderr, "Failed to get new netdev name\n"); +- goto out_err; ++ usernic_error("Failed to get new netdev name: %s.\n", strerror(errno)); ++ goto do_full_cleanup; + } ++ + *newnamep = strdup(namep); + if (!*newnamep) +- goto out_err; ++ goto do_full_cleanup; + } +- if (setns(ofd, 0) < 0) { +- fprintf(stderr, "Error returning to original netns\n"); +- close(ofd); +- return -1; ++ ++ fret = 0; ++ ++do_full_cleanup: ++ ret = setresuid(ruid, euid, suid); ++ if (ret < 0) { ++ usernic_error("Failed to restore privilege by setting effective " ++ "user id to %d, real user id to %d, and saved user " ++ "ID to %d: %s.\n", ++ ruid, euid, suid, strerror(errno)); ++ fret = -1; ++ // COMMENT(brauner): setns() should fail if setresuid() doesn't ++ // succeed but there's no harm in falling through; keeps the ++ // code cleaner. + } +- close(ofd); + +- return 0; ++ ret = setns(ofd, CLONE_NEWNET); ++ if (ret < 0) { ++ usernic_error("Failed to setns() to original network namespace " ++ "of PID %d: %s.\n", ++ ofd, strerror(errno)); ++ fret = -1; ++ } + +-out_err: +- if (ofd >= 0) +- close(ofd); +- if (setns(ofd, 0) < 0) +- fprintf(stderr, "Error returning to original network namespace\n"); ++do_partial_cleanup: + if (fd >= 0) + close(fd); +- return -1; ++ close(ofd); ++ ++ return fret; + } + + /* +-- +2.1.4 + diff --git a/debian/patches/series b/debian/patches/series index 35ae8f9..164f464 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -6,3 +6,4 @@ 0006-start-initutils-make-cgroupns-separation-level-confi.patch 0007-rename-cgroup-namespace-directory-to-ns.patch 0008-possibility-to-run-lxc-monitord-as-a-regular-daemon.patch +0009-CVE-2017-5985-Ensure-target-netns-is-caller-owned.patch