Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
Ohai, I would like to upload lxc/1:2.0.7-2 for Stretch and seek your (pre-)approval. The main reason for the upload is to fix #857295 aka CVE-2017-5985: lxc-user-nic didn't verify network namespace ownership The patch for that is straight from upstream's stable-2.0 branch. The attached debdiff also contains two small unrelated changes: * use bash-completion's pkg-config instead of hard coding paths * ignore one autopkg test when the kernel has no overlay support Both should be safe, but I can take them out if you say so. Thanks for taking care of Stretch Evgeni -- System Information: Debian Release: 9.0 APT prefers unstable-debug APT policy: (500, 'unstable-debug'), (500, 'unstable'), (500, 'testing'), (1, 'experimental') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 4.9.0-1-amd64 (SMP w/4 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system)
diff --git a/debian/changelog b/debian/changelog index 51c8e86..d7d10c1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +lxc (1:2.0.7-2) unstable; urgency=high + + * use bash-completion's pkg-config support and don't move files around + * ignore lxc-test-cloneconfig if kernel has no overlay support + * CVE-2017-5985: Ensure target netns is caller-owned (Closes: #857295) + + -- Evgeni Golov <evg...@debian.org> Sat, 11 Mar 2017 09:47:20 +0100 + lxc (1:2.0.7-1) unstable; urgency=medium * New upstream version 2.0.7 diff --git a/debian/control b/debian/control index d2fd241..b6c63bb 100644 --- a/debian/control +++ b/debian/control @@ -4,6 +4,7 @@ Priority: optional Maintainer: pkg-lxc <pkg-lxc-de...@lists.alioth.debian.org> Uploaders: Antonio Terceiro <terce...@debian.org>, Evgeni Golov <evg...@debian.org> Build-Depends: autotools-dev, + bash-completion, debhelper (>= 9.20160114), dh-apparmor, dh-autoreconf, diff --git a/debian/lxc.install b/debian/lxc.install index dd76dae..dfa72e7 100644 --- a/debian/lxc.install +++ b/debian/lxc.install @@ -5,6 +5,7 @@ usr/lib/*/lxc/lxc-* usr/lib/*/lxc/rootfs usr/lib/*/lxc/hooks usr/sbin +usr/share/bash-completion usr/share/doc usr/share/lxc usr/share/man diff --git a/debian/patches/lxc-2.0-CVE-2017-5985-Ensure-target-netns-is-caller-owned.patch b/debian/patches/lxc-2.0-CVE-2017-5985-Ensure-target-netns-is-caller-owned.patch new file mode 100644 index 0000000..9570f12 --- /dev/null +++ b/debian/patches/lxc-2.0-CVE-2017-5985-Ensure-target-netns-is-caller-owned.patch @@ -0,0 +1,188 @@ +From d512bd5efb0e407eba350c4e649c464a65b712a3 Mon Sep 17 00:00:00 2001 +From: Christian Brauner <christian.brau...@ubuntu.com> +Date: Sat, 28 Jan 2017 13:02:34 +0100 +Subject: [PATCH] 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 <ja...@google.com> +Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com> +--- + 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 409a53a1..96dc3986 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.11.0 + diff --git a/debian/patches/series b/debian/patches/series index f4f36e4..b99ca55 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1 +1,2 @@ 0010-lxc-debian-root-password.patch +lxc-2.0-CVE-2017-5985-Ensure-target-netns-is-caller-owned.patch diff --git a/debian/rules b/debian/rules index dc00608..7d334ad 100755 --- a/debian/rules +++ b/debian/rules @@ -35,9 +35,7 @@ override_dh_auto_install: find debian/tmp/ -type f -name \*.la -delete # lxc - mkdir -p debian/lxc/usr/share/bash-completion - mv debian/tmp/etc/bash_completion.d debian/lxc/usr/share/bash-completion/completions - grep complete debian/lxc/usr/share/bash-completion/completions/lxc | sed "s/.* //g" | while read cmd; do \ + grep complete debian/tmp/usr/share/bash-completion/completions/lxc | sed "s/.* //g" | while read cmd; do \ dh_link -p lxc usr/share/bash-completion/completions/lxc usr/share/bash-completion/completions/$${cmd}; \ done diff --git a/debian/tests/exercise b/debian/tests/exercise index 8a1f8f8..8b259cc 100755 --- a/debian/tests/exercise +++ b/debian/tests/exercise @@ -119,6 +119,12 @@ for testbin in /usr/bin/lxc-test-*; do ignore "$STRING" && continue fi + # Skip overlay tests when kernel has no overlay support + if ! grep -q overlay /proc/filesystems; then + [ "$testbin" = "/usr/bin/lxc-test-cloneconfig" ] && \ + ignore "$STRING" && continue + fi + OUT=$(mktemp) $testbin >$OUT 2>&1 && pass "$STRING" || fail "$STRING" "$testbin" "$OUT" rm $OUT