Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:Update
libvirt.10484
libvirt-qemu-capabilities-force-update-if-the-m...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File libvirt-qemu-capabilities-force-update-if-the-microcode-version-does-not-match.patch of Package libvirt.10484
From 880bf81b173e53c53427a7b22ae577ecc0d48038 Mon Sep 17 00:00:00 2001 Message-Id: <880bf81b173e53c53427a7b22ae577ecc0d48038@dist-git> From: Paolo Bonzini <pbonzini@redhat.com> Date: Tue, 12 Dec 2017 16:23:41 +0100 Subject: [PATCH] qemu: capabilities: force update if the microcode version does not match A microcode update can cause the CPUID bits to change; an example from the past was the update that disabled TSX on several Haswell and Broadwell machines. Therefore, place microcode version in the virQEMUCaps struct and XML, and rebuild the cache if the versions do not match. CVE-2017-5715 Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Jiri Denemark <jdenemar@redhat.com> Conflicts: src/qemu/qemu_capabilities.c src/qemu/qemu_capabilities.h - QEMU capabilities cache was refactored since 7.3 src/qemu/qemu_capspriv.h - context; more functions were added since 7.3 tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml - context; different package version in 7.3 tests/qemucapabilitiesdata/caps_2.10.0-gicv2.aarch64.xml tests/qemucapabilitiesdata/caps_2.10.0-gicv3.aarch64.xml tests/qemucapabilitiesdata/caps_2.10.0.ppc64.xml tests/qemucapabilitiesdata/caps_2.10.0.s390x.xml tests/qemucapabilitiesdata/caps_2.10.0.x86_64.xml tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml tests/qemucapabilitiesdata/caps_2.9.0.ppc64.xml tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml - missing in 7.3 tests/qemucapabilitiestest.c - no explicit TCG caps probing for KVM binaries in 7.3 yet tests/qemucapsprobe.c - the caps parameter for virQEMUCapsNewForBinaryInternal added in 7.4 is missing in 7.3 (which matches 7.5 in this respect) Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_capabilities.c | 57 ++++++++++++++++++++-- src/qemu/qemu_capspriv.h | 5 ++ tests/qemucapabilitiesdata/caps_1.2.2.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_1.3.1.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_1.4.2.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_1.5.3.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_1.6.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_1.7.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.1.1.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml | 1 + .../caps_2.6.0-gicv2.aarch64.xml | 1 + .../caps_2.6.0-gicv3.aarch64.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml | 1 + tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml | 1 + tests/qemucapabilitiestest.c | 8 +++ tests/qemucapsprobe.c | 2 +- 18 files changed, 80 insertions(+), 6 deletions(-) Index: libvirt-1.2.18.4/src/qemu/qemu_capabilities.c =================================================================== --- libvirt-1.2.18.4.orig/src/qemu/qemu_capabilities.c +++ libvirt-1.2.18.4/src/qemu/qemu_capabilities.c @@ -310,6 +310,7 @@ struct _virQEMUCaps { unsigned int version; unsigned int kvmVersion; + unsigned int microcodeVersion; char *package; virArch arch; @@ -330,6 +331,7 @@ struct _virQEMUCapsCache { char *cacheDir; uid_t runUid; gid_t runGid; + unsigned int microcodeVersion; }; struct virQEMUCapsSearchData { @@ -2000,6 +2002,7 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEM ret->usedQMP = qemuCaps->usedQMP; ret->version = qemuCaps->version; ret->kvmVersion = qemuCaps->kvmVersion; + ret->microcodeVersion = qemuCaps->microcodeVersion; if (VIR_STRDUP(ret->package, qemuCaps->package) < 0) goto error; @@ -2788,6 +2791,13 @@ virQEMUCapsLoadCache(virQEMUCapsPtr qemu /* Don't check for NULL, since it is optional and thus may be missing */ qemuCaps->package = virXPathString("string(./package)", ctxt); + if (virXPathUInt("string(./microcodeVersion)", ctxt, + &qemuCaps->microcodeVersion) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing microcode version in QEMU capabilities cache")); + goto cleanup; + } + if (!(str = virXPathString("string(./arch)", ctxt))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing arch in QEMU capabilities cache")); @@ -2901,6 +2911,9 @@ virQEMUCapsSaveCache(virQEMUCapsPtr qemu virBufferAsprintf(&buf, "<kvmVersion>%d</kvmVersion>\n", qemuCaps->kvmVersion); + virBufferAsprintf(&buf, "<microcodeVersion>%u</microcodeVersion>\n", + qemuCaps->microcodeVersion); + if (qemuCaps->package) virBufferAsprintf(&buf, "<package>%s</package>\n", qemuCaps->package); @@ -3016,7 +3029,8 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps static int virQEMUCapsInitCached(virQEMUCapsPtr qemuCaps, - const char *cacheDir) + const char *cacheDir, + unsigned int microcodeVersion) { char *capsdir = NULL; char *capsfile = NULL; @@ -3070,6 +3084,20 @@ virQEMUCapsInitCached(virQEMUCapsPtr qem goto cleanup; } + if ((virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) || + virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM)) && + microcodeVersion != qemuCaps->microcodeVersion) { + VIR_DEBUG("Outdated capabilities for '%s': microcode version changed " + "(%u vs %u)", + qemuCaps->binary, + microcodeVersion, + qemuCaps->microcodeVersion); + ignore_value(unlink(capsfile)); + virQEMUCapsReset(qemuCaps); + ret = 0; + goto cleanup; + } + /* Discard cache if QEMU binary or libvirtd changed */ if (qemuctime != qemuCaps->ctime || selfctime != virGetSelfLastChanged() || @@ -3558,7 +3586,8 @@ virQEMUCapsPtr virQEMUCapsNewForBinary(c const char *libDir, const char *cacheDir, uid_t runUid, - gid_t runGid) + gid_t runGid, + unsigned int microcodeVersion) { virQEMUCapsPtr qemuCaps; struct stat sb; @@ -3590,7 +3619,7 @@ virQEMUCapsPtr virQEMUCapsNewForBinary(c goto error; } - if ((rv = virQEMUCapsInitCached(qemuCaps, cacheDir)) < 0) + if ((rv = virQEMUCapsInitCached(qemuCaps, cacheDir, microcodeVersion)) < 0) goto error; if (rv == 0) { @@ -3605,6 +3634,10 @@ virQEMUCapsPtr virQEMUCapsNewForBinary(c goto error; } + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) || + virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM)) + qemuCaps->microcodeVersion = microcodeVersion; + if (virQEMUCapsRememberCached(qemuCaps, cacheDir) < 0) goto error; } @@ -3678,6 +3711,9 @@ virQEMUCapsCacheNew(const char *libDir, { virQEMUCapsCachePtr cache; + if (virQEMUCapsInitialize() < 0) + return NULL; + if (VIR_ALLOC(cache) < 0) return NULL; @@ -3697,6 +3733,7 @@ virQEMUCapsCacheNew(const char *libDir, cache->runUid = runUid; cache->runGid = runGid; + cache->microcodeVersion = cpuMicrocodeVersion; return cache; @@ -3724,7 +3761,8 @@ virQEMUCapsCacheLookup(virQEMUCapsCacheP binary); ret = virQEMUCapsNewForBinary(binary, cache->libDir, cache->cacheDir, - cache->runUid, cache->runGid); + cache->runUid, cache->runGid, + cache->microcodeVersion); if (ret) { VIR_DEBUG("Caching capabilities %p for %s", ret, binary); @@ -4026,3 +4064,11 @@ virQEMUCapsFillDomainCaps(virDomainCapsP return -1; return 0; } + + +void +virQEMUCapsSetMicrocodeVersion(virQEMUCapsPtr qemuCaps, + unsigned int microcodeVersion) +{ + qemuCaps->microcodeVersion = microcodeVersion; +} Index: libvirt-1.2.18.4/tests/qemucapabilitiestest.c =================================================================== --- libvirt-1.2.18.4.orig/tests/qemucapabilitiestest.c +++ libvirt-1.2.18.4/tests/qemucapabilitiestest.c @@ -142,6 +142,14 @@ testQemuCaps(const void *opaque) qemuMonitorTestGetMonitor(mon)) < 0) goto cleanup; + if (virQEMUCapsGet(capsComputed, QEMU_CAPS_KVM) || + virQEMUCapsGet(capsComputed, QEMU_CAPS_ENABLE_KVM)) { + /* Fill microcodeVersion with a "random" value which is the file + * length to provide a reproducible number for testing. + */ + virQEMUCapsSetMicrocodeVersion(capsComputed, virFileLength(repliesFile, -1)); + } + if (testQemuCapsCompare(capsProvided, capsComputed) < 0) goto cleanup; Index: libvirt-1.2.18.4/src/qemu/qemu_capabilities.h =================================================================== --- libvirt-1.2.18.4.orig/src/qemu/qemu_capabilities.h +++ libvirt-1.2.18.4/src/qemu/qemu_capabilities.h @@ -247,7 +247,8 @@ virQEMUCapsPtr virQEMUCapsNewForBinary(c const char *libDir, const char *cacheDir, uid_t runUid, - gid_t runGid); + gid_t runGid, + unsigned int microcodeVersion); int virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, qemuMonitorPtr mon);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor