From c314537c3f4cf48e710a4870174254db34c164d7 Mon Sep 17 00:00:00 2001 Message-Id: <c314537c3f4cf48e710a4870174254db34c164d7.1305127060.git.jdenemar@redhat.com> From: Eric Blake <eblake@redhat.com> Date: Mon, 9 May 2011 17:22:21 -0600 Subject: [PATCH] uuid: require smbios uuid and domain uuid to match https://bugzilla.redhat.com/show_bug.cgi?id=661365 * src/conf/domain_conf.c (virDomainDefParseXML): Prefer sysinfo uuid over generating one, and if both uuids are present, require them to be identical. * src/qemu/qemu_conf.c (qemuBuildSmbiosSystemStr): Allow skipping the uuid. (qemudBuildCommandLine): Adjust caller; <smbios mode=host/> must not use host uuid in place of guest uuid. (cherry picked from commit 4117672eaa7ccb3b2f17d6b761e2499ff9a77d6e) --- src/conf/domain_conf.c | 22 +++++++++++++++++++++- src/qemu/qemu_conf.c | 18 +++++++++++------- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 8697654..cfc2f6d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4066,6 +4066,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, long id = -1; virDomainDefPtr def; unsigned long count; + bool uuid_generated = false; if (VIR_ALLOC(def) < 0) { virReportOOMError(); @@ -4097,7 +4098,9 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, goto error; } - /* Extract domain uuid */ + /* Extract domain uuid. If both uuid and sysinfo/system/entry/uuid + * exist, they must match; and if only the latter exists, it can + * also serve as the uuid. */ tmp = virXPathString("string(./uuid[1])", ctxt); if (!tmp) { if (virUUIDGenerate(def->uuid)) { @@ -4105,6 +4108,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, "%s", _("Failed to generate UUID")); goto error; } + uuid_generated = true; } else { if (virUUIDParse(tmp, def->uuid) < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, @@ -4801,6 +4805,22 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, if (def->sysinfo == NULL) goto error; + if (def->sysinfo->system_uuid != NULL) { + unsigned char uuidbuf[VIR_UUID_BUFLEN]; + if (virUUIDParse(def->sysinfo->system_uuid, uuidbuf) < 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("malformed uuid element")); + goto error; + } + if (uuid_generated) + memcpy(def->uuid, uuidbuf, VIR_UUID_BUFLEN); + else if (memcmp(def->uuid, uuidbuf, VIR_UUID_BUFLEN) != 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("UUID mismatch between <uuid> and " + "<sysinfo>")); + goto error; + } + } } tmp = virXPathString("string(./os/smbios/@mode)", ctxt); if (tmp) { diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 49a1856..532e691 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -3332,15 +3332,15 @@ error: return(NULL); } -static char *qemuBuildSmbiosSystemStr(virSysinfoDefPtr def) +static char *qemuBuildSmbiosSystemStr(virSysinfoDefPtr def, bool skip_uuid) { virBuffer buf = VIR_BUFFER_INITIALIZER; if ((def->system_manufacturer == NULL) && (def->system_sku == NULL) && - (def->system_product == NULL) && (def->system_uuid == NULL) && - (def->system_version == NULL) && (def->system_serial == NULL) && - (def->system_family == NULL)) - return(NULL); + (def->system_product == NULL) && (def->system_version == NULL) && + (def->system_serial == NULL) && (def->system_family == NULL) && + (def->system_uuid == NULL || skip_uuid)) + return NULL; virBufferAddLit(&buf, "type=1"); @@ -3358,7 +3358,7 @@ static char *qemuBuildSmbiosSystemStr(virSysinfoDefPtr def) if (def->system_serial) virBufferVSprintf(&buf, ",serial=%s", def->system_serial); /* 1:UUID */ - if (def->system_uuid) + if (def->system_uuid && !skip_uuid) virBufferVSprintf(&buf, ",uuid=%s", def->system_uuid); /* 1:SKU Number */ if (def->system_sku) @@ -3904,6 +3904,7 @@ int qemudBuildCommandLine(virConnectPtr conn, if ((def->os.smbios_mode != VIR_DOMAIN_SMBIOS_NONE) && (def->os.smbios_mode != VIR_DOMAIN_SMBIOS_EMULATE)) { virSysinfoDefPtr source = NULL; + bool skip_uuid = false; if (!(qemuCmdFlags & QEMUD_CMD_FLAG_SMBIOS_TYPE)) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -3920,6 +3921,8 @@ int qemudBuildCommandLine(virConnectPtr conn, goto error; } source = driver->hostsysinfo; + /* Host and guest uuid must differ, by definition of UUID. */ + skip_uuid = true; } else if (def->os.smbios_mode == VIR_DOMAIN_SMBIOS_SYSINFO) { if (def->sysinfo == NULL) { qemuReportError(VIR_ERR_XML_ERROR, @@ -3928,6 +3931,7 @@ int qemudBuildCommandLine(virConnectPtr conn, goto error; } source = def->sysinfo; + /* domain_conf guaranteed that system_uuid matches guest uuid. */ } if (source != NULL) { char *smbioscmd; @@ -3937,7 +3941,7 @@ int qemudBuildCommandLine(virConnectPtr conn, ADD_ARG_LIT("-smbios"); ADD_ARG(smbioscmd); } - smbioscmd = qemuBuildSmbiosSystemStr(source); + smbioscmd = qemuBuildSmbiosSystemStr(source, skip_uuid); if (smbioscmd != NULL) { ADD_ARG_LIT("-smbios"); ADD_ARG(smbioscmd); -- 1.7.5.rc3