From b7a92bce070fd57844a59bf8b1c30cb4ef4f3acd Mon Sep 17 00:00:00 2001 From: Laine Stump Date: Thu, 18 Jun 2020 12:49:09 -0400 Subject: [PATCH] conf, vmx: check for OOM after calling xmlBufferCreate() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although libvirt itself uses g_malloc0() and friends, which exit when there isn't enouogh memory, libxml2 uses standard malloc(), which just returns NULL on OOM - this means we must check for NULL on return from any libxml2 functions that allocate memory. xmlBufferCreate(), for example, might return NULL, and we don't always check for it. This patch adds checks where it isn't already done. (NB: Although libxml2 has a provision for changing behavior on OOM (by calling xmlMemSetup() to change what functions are used to allocating/freeing memory), we can't use that, since parts of libvirt code end up in libvirt.so, which is linked and called directly by applications that may themselves use libxml2 (and may have already set their own alternate malloc()), e.g. drivers like esx which live totally in the library rather than a separate process.) Signed-off-by: Laine Stump Reviewed-by: Ján Tomko --- src/conf/domain_conf.c | 6 +++++- src/conf/network_conf.c | 6 +++++- src/vmx/vmx.c | 11 +++++++---- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0c883cd834..40b2c57fe5 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -29589,7 +29589,11 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr def, * Thankfully, libxml maps what looks like globals into * thread-local uses, so we are thread-safe. */ xmlIndentTreeOutput = 1; - xmlbuf = xmlBufferCreate(); + if (!(xmlbuf = xmlBufferCreate())) { + virReportOOMError(); + goto error; + } + if (xmlNodeDump(xmlbuf, def->metadata->doc, def->metadata, virBufferGetIndent(buf) / 2, 1) < 0) { xmlBufferFree(xmlbuf); diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 87d43de1e3..5b578f894c 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -2518,7 +2518,11 @@ virNetworkDefFormatBuf(virBufferPtr buf, * Thankfully, libxml maps what looks like globals into * thread-local uses, so we are thread-safe. */ xmlIndentTreeOutput = 1; - xmlbuf = xmlBufferCreate(); + if (!(xmlbuf = xmlBufferCreate())) { + virReportOOMError(); + return -1; + } + if (xmlNodeDump(xmlbuf, def->metadata->doc, def->metadata, virBufferGetIndent(buf) / 2, 1) < 0) { xmlBufferFree(xmlbuf); diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index f2248cef53..263b57e177 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -697,8 +697,8 @@ virVMXConvertToUTF8(const char *encoding, const char *string) { char *result = NULL; xmlCharEncodingHandlerPtr handler; - xmlBufferPtr input; - xmlBufferPtr utf8; + xmlBufferPtr input = NULL; + xmlBufferPtr utf8 = NULL; handler = xmlFindCharEncodingHandler(encoding); @@ -708,8 +708,11 @@ virVMXConvertToUTF8(const char *encoding, const char *string) return NULL; } - input = xmlBufferCreateStatic((char *)string, strlen(string)); - utf8 = xmlBufferCreate(); + if (!(input = xmlBufferCreateStatic((char *)string, strlen(string))) || + !(utf8 = xmlBufferCreate())) { + virReportOOMError(); + goto cleanup; + } if (xmlCharEncInFunc(handler, utf8, input) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR,