From patchwork Fri Mar 10 13:04:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Korsgaard X-Patchwork-Id: 737405 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3vfnXG65Zpz9s7p for ; Sat, 11 Mar 2017 00:04:14 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="BQgiEWVR"; dkim-atps=neutral Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 45CBE8A1BA; Fri, 10 Mar 2017 13:04:11 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8W+z-Rlx8C94; Fri, 10 Mar 2017 13:04:09 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by whitealder.osuosl.org (Postfix) with ESMTP id 0E50B89F86; Fri, 10 Mar 2017 13:04:09 +0000 (UTC) X-Original-To: buildroot@lists.busybox.net Delivered-To: buildroot@osuosl.org Received: from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by ash.osuosl.org (Postfix) with ESMTP id 17EE61C0385 for ; Fri, 10 Mar 2017 13:04:07 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 106848ABAB for ; Fri, 10 Mar 2017 13:04:07 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id QoO7S3bwmxJw for ; Fri, 10 Mar 2017 13:04:06 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mail-wm0-f68.google.com (mail-wm0-f68.google.com [74.125.82.68]) by hemlock.osuosl.org (Postfix) with ESMTPS id C1F438ABBD for ; Fri, 10 Mar 2017 13:04:05 +0000 (UTC) Received: by mail-wm0-f68.google.com with SMTP id z63so2211759wmg.2 for ; Fri, 10 Mar 2017 05:04:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id; bh=xS1HMRF8GR3YS49tG1fXFfDBXvR7gxo1iSIkyF0dyF8=; b=BQgiEWVRqb+DQcjgSywRqo+xS0sOSlD0cAa0an458iaBDP8p0BIQkcpH9ACbhlPYF0 z1jHAlVhMrW/yLr4+vYyI5dSuQTEOE3PaJ+K8UVcNByS5/1HLolonVteC7QJtzIryJnb RE5+10AEPcs9XO+ibPFjbGVnItcgHU6OfOa+ijmI/btPcPF4MnnhsKsaep8LirqjmE3r Jh6njPxkYSEMOgXGht8vXfsBIy46q69Z8vEh0ZTt8SRt0Hdjc2PHRpi7+BOFY+YrkviB MfemZzzXt1BvN2EVrIR1BZQqXa+yijx4hD9LBlmrulsmlmXmaFK+kQl06XcFJ07jg4+6 MhvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=xS1HMRF8GR3YS49tG1fXFfDBXvR7gxo1iSIkyF0dyF8=; b=tJNJqkxpQflJvy9dceDa/1u/30RscRhix5nW8cIujp5s++J5Zdu34+StyUk8wC8N38 1lzWcYL5+VESZ5UCuWzYfNJHU30bZ7aQDtHLuq0nKpWeFZFPxyEs3tKsUjiKwXjZWQih XbfL2ZHp70J/oSmy5v1QE0T0x8Uj+WYN7JQCWMQtbzaMig2fNJ6OYjIrT9qgHyGY9Hmv cK5aWg1j5UHj5xrIp5GzlciXi0LzQ9yVLE98oLL/3VR3rz4lLkIgkcIXEvcE8zJ7cXbE 0Sq1jQFD9e+qaF3vB3eaMSZUAeXjPF93SyqtgLo/yo5BHwEk/hqpvHpeCk6/0LmOJlQF 26lQ== X-Gm-Message-State: AFeK/H0hlYId91gprMad5KGTE5aKZ/2++tsjgEkUtI0YDMxrTFDAB+ydVkd/5JCdX+vWBg== X-Received: by 10.28.109.93 with SMTP id i90mr2430616wmc.44.1489151043211; Fri, 10 Mar 2017 05:04:03 -0800 (PST) Received: from dell.be.48ers.dk ([91.183.172.93]) by smtp.gmail.com with ESMTPSA id r8sm12786141wrb.33.2017.03.10.05.04.02 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 10 Mar 2017 05:04:02 -0800 (PST) Received: from peko by dell.be.48ers.dk with local (Exim 4.88) (envelope-from ) id 1cmKDB-0002Cb-KL; Fri, 10 Mar 2017 14:04:01 +0100 From: Peter Korsgaard To: buildroot@buildroot.org Date: Fri, 10 Mar 2017 14:04:00 +0100 Message-Id: <20170310130400.8425-1-peter@korsgaard.com> X-Mailer: git-send-email 2.11.0 Subject: [Buildroot] [PATCH] lxc: add upstream security fix for CVE-2017-5985 X-BeenThere: buildroot@busybox.net X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Discussion and development of buildroot List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: buildroot-bounces@busybox.net Sender: "buildroot" 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. Signed-off-by: Peter Korsgaard --- ...-5985-Ensure-target-netns-is-caller-owned.patch | 189 +++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 package/lxc/0001-CVE-2017-5985-Ensure-target-netns-is-caller-owned.patch diff --git a/package/lxc/0001-CVE-2017-5985-Ensure-target-netns-is-caller-owned.patch b/package/lxc/0001-CVE-2017-5985-Ensure-target-netns-is-caller-owned.patch new file mode 100644 index 000000000..79d19b3af --- /dev/null +++ b/package/lxc/0001-CVE-2017-5985-Ensure-target-netns-is-caller-owned.patch @@ -0,0 +1,189 @@ +From 16af238036a5464ae8f2420ed3af214f0de875f9 Mon Sep 17 00:00:00 2001 +From: Christian Brauner +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 +Signed-off-by: Christian Brauner +Signed-off-by: Peter Korsgaard +--- + 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 +