diff options
Diffstat (limited to 'app-emulation/lxc/files/lxc-2.1.1-cve-2018-6556.patch')
-rw-r--r-- | app-emulation/lxc/files/lxc-2.1.1-cve-2018-6556.patch | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/app-emulation/lxc/files/lxc-2.1.1-cve-2018-6556.patch b/app-emulation/lxc/files/lxc-2.1.1-cve-2018-6556.patch new file mode 100644 index 000000000000..bad1e274527e --- /dev/null +++ b/app-emulation/lxc/files/lxc-2.1.1-cve-2018-6556.patch @@ -0,0 +1,118 @@ +From d183654ec1a2cd1149bdb92601ccb7246bddb14e Mon Sep 17 00:00:00 2001 +From: Christian Brauner <christian.brauner@ubuntu.com> +Date: Wed, 25 Jul 2018 19:56:54 +0200 +Subject: [PATCH] CVE 2018-6556: verify netns fd in lxc-user-nic + +Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com> +--- + src/lxc/lxc_user_nic.c | 35 ++++++++++++++++++++++++++++++++--- + src/lxc/utils.c | 12 ++++++++++++ + src/lxc/utils.h | 5 +++++ + 3 files changed, 49 insertions(+), 3 deletions(-) + +ADDENDUM from vdupras@gentoo.org: Original patch from Christian didn't +include LXC_PROC_PID_FD_LEN define, but referenced it. This resulted in +code that doesn't compile. I fetched the definition from the stable-3.0 +branch and included it to this patch. Also, this diff is regenerated +from lxc-2.1.1 tag instead of stable-2.0 branch. + +diff --git a/src/lxc/lxc_user_nic.c b/src/lxc/lxc_user_nic.c +index 6f550f0d..09a342ac 100644 +--- a/src/lxc/lxc_user_nic.c ++++ b/src/lxc/lxc_user_nic.c +@@ -1124,12 +1124,41 @@ int main(int argc, char *argv[]) + exit(EXIT_FAILURE); + } + } else if (request == LXC_USERNIC_DELETE) { +- netns_fd = open(args.pid, O_RDONLY); ++ char opath[LXC_PROC_PID_FD_LEN]; ++ ++ /* Open the path with O_PATH which will not trigger an actual ++ * open(). Don't report an errno to the caller to not leak ++ * information whether the path exists or not. ++ * When stracing setuid is stripped so this is not a concern ++ * either. ++ */ ++ netns_fd = open(args.pid, O_PATH | O_CLOEXEC); + if (netns_fd < 0) { +- usernic_error("Could not open \"%s\": %s\n", args.pid, +- strerror(errno)); ++ usernic_error("Failed to open \"%s\"\n", args.pid); + exit(EXIT_FAILURE); + } ++ ++ if (!fhas_fs_type(netns_fd, NSFS_MAGIC)) { ++ usernic_error("Path \"%s\" does not refer to a network namespace path\n", args.pid); ++ close(netns_fd); ++ exit(EXIT_FAILURE); ++ } ++ ++ ret = snprintf(opath, sizeof(opath), "/proc/self/fd/%d", netns_fd); ++ if (ret < 0 || (size_t)ret >= sizeof(opath)) { ++ close(netns_fd); ++ exit(EXIT_FAILURE); ++ } ++ ++ /* Now get an fd that we can use in setns() calls. */ ++ ret = open(opath, O_RDONLY | O_CLOEXEC); ++ if (ret < 0) { ++ usernic_error("Failed to open \"%s\": %s\n", args.pid, strerror(errno)); ++ close(netns_fd); ++ exit(EXIT_FAILURE); ++ } ++ close(netns_fd); ++ netns_fd = ret; + } + + if (!create_db_dir(LXC_USERNIC_DB)) { +diff --git a/src/lxc/utils.c b/src/lxc/utils.c +index e6a44a51..c2a08a9d 100644 +--- a/src/lxc/utils.c ++++ b/src/lxc/utils.c +@@ -2380,6 +2380,18 @@ bool has_fs_type(const char *path, fs_type_magic magic_val) + return has_type; + } + ++bool fhas_fs_type(int fd, fs_type_magic magic_val) ++{ ++ int ret; ++ struct statfs sb; ++ ++ ret = fstatfs(fd, &sb); ++ if (ret < 0) ++ return false; ++ ++ return is_fs_type(&sb, magic_val); ++} ++ + bool lxc_nic_exists(char *nic) + { + #define __LXC_SYS_CLASS_NET_LEN 15 + IFNAMSIZ + 1 +diff --git a/src/lxc/utils.h b/src/lxc/utils.h +index e83ed49e..06ec74d7 100644 +--- a/src/lxc/utils.h ++++ b/src/lxc/utils.h +@@ -46,11 +46,16 @@ + #define __S_ISTYPE(mode, mask) (((mode)&S_IFMT) == (mask)) + #endif + ++#ifndef NSFS_MAGIC ++#define NSFS_MAGIC 0x6e736673 ++#endif ++ + /* Useful macros */ + /* Maximum number for 64 bit integer is a string with 21 digits: 2^64 - 1 = 21 */ + #define LXC_NUMSTRLEN64 21 + #define LXC_LINELEN 4096 + #define LXC_IDMAPLEN 4096 ++#define LXC_PROC_PID_FD_LEN (6 + LXC_NUMSTRLEN64 + 4 + LXC_NUMSTRLEN64 + 1) + + /* returns 1 on success, 0 if there were any failures */ + extern int lxc_rmdir_onedev(char *path, const char *exclude); +@@ -402,6 +407,7 @@ extern void *must_realloc(void *orig, size_t sz); + /* __typeof__ should be safe to use with all compilers. */ + typedef __typeof__(((struct statfs *)NULL)->f_type) fs_type_magic; + extern bool has_fs_type(const char *path, fs_type_magic magic_val); ++extern bool fhas_fs_type(int fd, fs_type_magic magic_val); + extern bool is_fs_type(const struct statfs *fs, fs_type_magic magic_val); + extern bool lxc_nic_exists(char *nic); |