From 3cb55cb51fb241b6ffe2583283a699c6a3450f71 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 30 Jan 2009 17:12:28 +0000 Subject: [PATCH] Fix crash using bogus arch in QEMU --- ChangeLog | 10 ++++++++++ src/capabilities.c | 24 ++++++++++++++++++++++++ src/capabilities.h | 6 ++++++ src/domain_conf.c | 9 ++++++++- src/qemu_conf.c | 12 ++++++++++-- 5 files changed, 58 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c332e201d3..d075e56170 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Fri Jan 30 16:12:22 GMT 2009 Daniel P. Berrange + + Fix crash when using bogus arch type + * src/capabilities.c, src/capabilities.h: Add method to query + for supported arch+ostype combo + * src/domain_conf.c: Validate requested arch+ostype against + supported capabilities + * src/qemu_conf.c: Sanity check to avoid deferencing NULL + machine type + Fri Jan 30 16:58:22 GMT 2009 Daniel P. Berrange Misc QEMU driver startup fixes diff --git a/src/capabilities.c b/src/capabilities.c index 158873ced9..3a2333207d 100644 --- a/src/capabilities.c +++ b/src/capabilities.c @@ -432,6 +432,30 @@ virCapabilitiesSupportsGuestOSType(virCapsPtr caps, } +/** + * virCapabilitiesSupportsGuestOSType: + * @caps: capabilities to query + * @ostype: OS type to search for (eg 'hvm', 'xen') + * @arch: Architecture to search for (eg, 'i686', 'x86_64') + * + * Returns non-zero if the capabilities support the + * requested operating system type + */ +extern int +virCapabilitiesSupportsGuestArch(virCapsPtr caps, + const char *ostype, + const char *arch) +{ + int i; + for (i = 0 ; i < caps->nguests ; i++) { + if (STREQ(caps->guests[i]->ostype, ostype) && + STREQ(caps->guests[i]->arch.name, arch)) + return 1; + } + return 0; +} + + /** * virCapabilitiesDefaultGuestArch: * @caps: capabilities to query diff --git a/src/capabilities.h b/src/capabilities.h index c991ea192d..be3296c1ef 100644 --- a/src/capabilities.h +++ b/src/capabilities.h @@ -162,6 +162,12 @@ virCapabilitiesAddGuestFeature(virCapsGuestPtr guest, extern int virCapabilitiesSupportsGuestOSType(virCapsPtr caps, const char *ostype); +extern int +virCapabilitiesSupportsGuestArch(virCapsPtr caps, + const char *ostype, + const char *arch); + + extern const char * virCapabilitiesDefaultGuestArch(virCapsPtr caps, const char *ostype); diff --git a/src/domain_conf.c b/src/domain_conf.c index adcd032221..1bf46f1f7e 100644 --- a/src/domain_conf.c +++ b/src/domain_conf.c @@ -2038,7 +2038,14 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn, } def->os.arch = virXPathString(conn, "string(./os/type[1]/@arch)", ctxt); - if (!def->os.arch) { + if (def->os.arch) { + if (!virCapabilitiesSupportsGuestArch(caps, def->os.type, def->os.arch)) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("os type '%s' & arch '%s' combination is not supported"), + def->os.type, def->os.arch); + goto error; + } + } else { const char *defaultArch = virCapabilitiesDefaultGuestArch(caps, def->os.type); if (defaultArch == NULL) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, diff --git a/src/qemu_conf.c b/src/qemu_conf.c index 890434f2da..b2d888341b 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -837,8 +837,16 @@ int qemudBuildCommandLine(virConnectPtr conn, ADD_ARG_LIT(emulator); ADD_ARG_LIT("-S"); - ADD_ARG_LIT("-M"); - ADD_ARG_LIT(vm->def->os.machine); + + /* This should *never* be NULL, since we always provide + * a machine in the capabilities data for QEMU. So this + * check is just here as a safety in case the unexpected + * happens */ + if (vm->def->os.machine) { + ADD_ARG_LIT("-M"); + ADD_ARG_LIT(vm->def->os.machine); + } + if (disableKQEMU) ADD_ARG_LIT("-no-kqemu"); ADD_ARG_LIT("-m");