diff --git a/c2dc6698-fix-deadlock-obtaining-hostname.patch b/c2dc6698-fix-deadlock-obtaining-hostname.patch new file mode 100644 index 0000000..b6bf51d --- /dev/null +++ b/c2dc6698-fix-deadlock-obtaining-hostname.patch @@ -0,0 +1,121 @@ +From c2dc6698c88fb591639e542c8ecb0076c54f3dfb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Mon, 12 Feb 2018 10:03:08 +0000 +Subject: [PATCH] log: fix deadlock obtaining hostname (related CVE-2018-6764) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The fix for CVE-2018-6764 introduced a potential deadlock scenario +that gets triggered by the NSS module when virGetHostname() calls +getaddrinfo to resolve the hostname: + + #0 0x00007f6e714b57e7 in futex_wait + #1 futex_wait_simple + #2 __pthread_once_slow + #3 0x00007f6e71d16e7d in virOnce + #4 0x00007f6e71d0997c in virLogInitialize + #5 0x00007f6e71d0a09a in virLogVMessage + #6 0x00007f6e71d09ffd in virLogMessage + #7 0x00007f6e71d0db22 in virObjectNew + #8 0x00007f6e71d0dbf1 in virObjectLockableNew + #9 0x00007f6e71d0d3e5 in virMacMapNew + #10 0x00007f6e71cdc50a in findLease + #11 0x00007f6e71cdcc56 in _nss_libvirt_gethostbyname4_r + #12 0x00007f6e724631fc in gaih_inet + #13 0x00007f6e72464697 in __GI_getaddrinfo + #14 0x00007f6e71d19e81 in virGetHostnameImpl + #15 0x00007f6e71d1a057 in virGetHostnameQuiet + #16 0x00007f6e71d09936 in virLogOnceInit + #17 0x00007f6e71d09952 in virLogOnce + #18 0x00007f6e714b5829 in __pthread_once_slow + #19 0x00007f6e71d16e7d in virOnce + #20 0x00007f6e71d0997c in virLogInitialize + #21 0x00007f6e71d0a09a in virLogVMessage + #22 0x00007f6e71d09ffd in virLogMessage + #23 0x00007f6e71d0db22 in virObjectNew + #24 0x00007f6e71d0dbf1 in virObjectLockableNew + #25 0x00007f6e71d0d3e5 in virMacMapNew + #26 0x00007f6e71cdc50a in findLease + #27 0x00007f6e71cdc839 in _nss_libvirt_gethostbyname3_r + #28 0x00007f6e71cdc724 in _nss_libvirt_gethostbyname2_r + #29 0x00007f6e7248f72f in __gethostbyname2_r + #30 0x00007f6e7248f494 in gethostbyname2 + #31 0x000056348c30c36d in hosts_keys + #32 0x000056348c30b7d2 in main + +Fortunately the extra stuff virGetHostname does is totally irrelevant to +the needs of the logging code, so we can just inline a call to the +native hostname() syscall directly. + +Signed-off-by: Daniel P. Berrangé +--- + cfg.mk | 2 +- + src/util/virlog.c | 20 ++++++++++++++------ + 2 files changed, 15 insertions(+), 7 deletions(-) + +Index: libvirt-4.0.0/cfg.mk +=================================================================== +--- libvirt-4.0.0.orig/cfg.mk ++++ libvirt-4.0.0/cfg.mk +@@ -1183,7 +1183,7 @@ _src2=src/(util/vircommand|libvirt|lxc/l + exclude_file_name_regexp--sc_prohibit_fork_wrappers = \ + (^($(_src2)|tests/testutils|daemon/libvirtd)\.c$$) + +-exclude_file_name_regexp--sc_prohibit_gethostname = ^src/util/virutil\.c$$ ++exclude_file_name_regexp--sc_prohibit_gethostname = ^src/util/vir(util|log)\.c$$ + + exclude_file_name_regexp--sc_prohibit_internal_functions = \ + ^src/(util/(viralloc|virutil|virfile)\.[hc]|esx/esx_vi\.c)$$ +Index: libvirt-4.0.0/src/util/virlog.c +=================================================================== +--- libvirt-4.0.0.orig/src/util/virlog.c ++++ libvirt-4.0.0/src/util/virlog.c +@@ -64,7 +64,7 @@ + VIR_LOG_INIT("util.log"); + + static regex_t *virLogRegex; +-static char *virLogHostname; ++static char virLogHostname[HOST_NAME_MAX+1]; + + + #define VIR_LOG_DATE_REGEX "[0-9]{4}-[0-9]{2}-[0-9]{2}" +@@ -261,6 +261,8 @@ virLogPriorityString(virLogPriority lvl) + static int + virLogOnceInit(void) + { ++ int r; ++ + if (virMutexInit(&virLogMutex) < 0) + return -1; + +@@ -275,8 +277,17 @@ virLogOnceInit(void) + /* We get and remember the hostname early, because at later time + * it might not be possible to load NSS modules via getaddrinfo() + * (e.g. at container startup the host filesystem will not be +- * accessible anymore. */ +- virLogHostname = virGetHostnameQuiet(); ++ * accessible anymore. ++ * Must not use virGetHostname though as that causes re-entrancy ++ * problems if it triggers logging codepaths ++ */ ++ r = gethostname(virLogHostname, sizeof(virLogHostname)); ++ if (r == -1) { ++ ignore_value(virStrcpy(virLogHostname, ++ "(unknown)", sizeof(virLogHostname))); ++ } else { ++ NUL_TERMINATE(virLogHostname); ++ } + + virLogUnlock(); + return 0; +@@ -475,9 +486,6 @@ virLogHostnameString(char **rawmsg, + { + char *hoststr; + +- if (!virLogHostname) +- return -1; +- + if (virAsprintfQuiet(&hoststr, "hostname: %s", virLogHostname) < 0) { + return -1; + } diff --git a/libvirt.changes b/libvirt.changes index 52e9888..26d5b52 100644 --- a/libvirt.changes +++ b/libvirt.changes @@ -7,6 +7,7 @@ Fri Feb 9 13:28:14 UTC 2018 - cbosdonnat@suse.com - Determine hostname early to avoid code injection in lxc driver. (bsc#1080042) 759b4d1b-virlog-determine-the-hostname-on-startup-CVE-2018-67.patch + c2dc6698-fix-deadlock-obtaining-hostname.patch - Add basic support of connectGetAllDomainStats for lxc driver (fate#323742) 0001-Extract-stats-functions-from-the-qemu-driver.patch diff --git a/libvirt.spec b/libvirt.spec index 9488569..f0926c0 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -324,6 +324,7 @@ Patch3: 76977061-qemu-smbios-oem-strings.patch Patch4: 0c710a37-libxl-resume-lock-on-mig-failure.patch Patch5: 6b3d716e-keycodemap-py3.patch Patch6: 759b4d1b-virlog-determine-the-hostname-on-startup-CVE-2018-67.patch +Patch7: c2dc6698-fix-deadlock-obtaining-hostname.patch # Patches pending upstream review Patch100: libxl-dom-reset.patch Patch101: network-don-t-use-dhcp-authoritative-on-static-netwo.patch @@ -922,6 +923,7 @@ pushd src/keycodemapdb %patch5 -p1 popd %patch6 -p1 +%patch7 -p1 %patch100 -p1 %patch101 -p1 %patch150 -p1