File 69958ba3-CVE-2025-12748-p1.patch of Package libvirt.42083
commit 2e3e9a6d65f1e78317296ea9e29e021a9badff00
Author: Michal Prívozník <mprivozn@redhat.com>
Date: Tue Nov 21 10:39:58 2023 +0100
virxml: Introduce parsing APIs that keep indentation
When parsing an XML it may be important to keep indentation to
produce a better looking result when formatting the XML back.
Just look at all those xmlKeepBlanksDefault() calls just before
virXMLParse() is called.
Anyway, as of libxml2 commit v2.12.0~108 xmlKeepBlanksDefault()
is deprecated. Therefore, introduce virXMLParse...WithIndent()
variants which would do exactly xmlKeepBlanksDefault() did but
with non-deprecated APIs.
References: bsc#1253278, CVE-2025-12748
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
(cherry picked from commit 69958ba3102810bb4f90a91d2f6d9032e1a1da2d)
Signed-off-by: Jim Fehlig <jfehlig@suse.com>
Index: libvirt-8.0.0/src/util/virxml.c
===================================================================
--- libvirt-8.0.0.orig/src/util/virxml.c
+++ libvirt-8.0.0/src/util/virxml.c
@@ -1038,13 +1038,15 @@ virXMLParseHelper(int domcode,
const char *rootelement,
xmlXPathContextPtr *ctxt,
const char *schemafile,
- bool validate)
+ bool validate,
+ bool keepindent)
{
struct virParserData private;
g_autoptr(xmlParserCtxt) pctxt = NULL;
g_autoptr(xmlDoc) xml = NULL;
xmlNodePtr rootnode;
const char *docname;
+ int parseFlags = XML_PARSE_NONET | XML_PARSE_NOWARNING;
if (filename)
docname = filename;
@@ -1062,14 +1064,14 @@ virXMLParseHelper(int domcode,
pctxt->_private = &private;
pctxt->sax->error = catchXMLError;
+ if (keepindent) {
+ parseFlags |= XML_PARSE_NOBLANKS;
+ }
+
if (filename) {
- xml = xmlCtxtReadFile(pctxt, filename, NULL,
- XML_PARSE_NONET |
- XML_PARSE_NOWARNING);
+ xml = xmlCtxtReadFile(pctxt, filename, NULL, parseFlags);
} else {
- xml = xmlCtxtReadDoc(pctxt, BAD_CAST xmlStr, url, NULL,
- XML_PARSE_NONET |
- XML_PARSE_NOWARNING);
+ xml = xmlCtxtReadDoc(pctxt, BAD_CAST xmlStr, url, NULL, parseFlags);
}
if (!xml) {
Index: libvirt-8.0.0/src/util/virxml.h
===================================================================
--- libvirt-8.0.0.orig/src/util/virxml.h
+++ libvirt-8.0.0/src/util/virxml.h
@@ -167,7 +167,8 @@ virXMLParseHelper(int domcode,
const char *rootelement,
xmlXPathContextPtr *ctxt,
const char *schemafile,
- bool validate);
+ bool validate,
+ bool keepindent);
const char *
virXMLPickShellSafeComment(const char *str1,
@@ -183,7 +184,17 @@ virXMLPickShellSafeComment(const char *s
* Return the parsed document object, or NULL on failure.
*/
#define virXMLParse(filename, xmlStr, url, schemafile, validate) \
- virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, NULL, NULL, schemafile, validate)
+ virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, NULL, NULL, schemafile, validate, false)
+
+/**
+ * virXMLParseWithIndent:
+ *
+ * Just like virXMLParse, except indentation is preserved. Should be used when
+ * facing an user provided XML which may be formatted back and keeping verbatim
+ * spacing is necessary (e.g. due to <metadata/>).
+ */
+#define virXMLParseWithIndent(filename, xmlStr, url, rootelement, ctxt, schemafile, validate) \
+ virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, rootelement, ctxt, schemafile, validate, true)
/**
* virXMLParseString:
@@ -195,7 +206,7 @@ virXMLPickShellSafeComment(const char *s
* Return the parsed document object, or NULL on failure.
*/
#define virXMLParseString(xmlStr, url) \
- virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL, NULL, NULL, false)
+ virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL, NULL, NULL, false, false)
/**
* virXMLParseFile:
@@ -206,7 +217,7 @@ virXMLPickShellSafeComment(const char *s
* Return the parsed document object, or NULL on failure.
*/
#define virXMLParseFile(filename) \
- virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, NULL, NULL, NULL, false)
+ virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, NULL, NULL, NULL, false, false)
/**
* virXMLParseCtxt:
@@ -221,7 +232,7 @@ virXMLPickShellSafeComment(const char *s
* Return the parsed document object, or NULL on failure.
*/
#define virXMLParseCtxt(filename, xmlStr, url, pctxt) \
- virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, NULL, pctxt, NULL, false)
+ virXMLParseHelper(VIR_FROM_THIS, filename, xmlStr, url, NULL, pctxt, NULL, false, false)
/**
* virXMLParseStringCtxt:
@@ -235,11 +246,21 @@ virXMLPickShellSafeComment(const char *s
* Return the parsed document object, or NULL on failure.
*/
#define virXMLParseStringCtxt(xmlStr, url, pctxt) \
- virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL, pctxt, NULL, false)
+ virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL, pctxt, NULL, false, false)
+
+/**
+ * virXMLParseStringCtxtWithIndent:
+ *
+ * Just like virXMLParseStringCtxt, except indentation is preserved. Should be
+ * used when facing an user provided XML which may be formatted back and
+ * keeping verbatim spacing is necessary (e.g. due to <metadata/>).
+ */
+#define virXMLParseStringCtxtWithIndent(xmlStr, url, pctxt) \
+ virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, NULL, pctxt, NULL, false, true)
/* virXMLParseStringCtxtRoot is same as above, except it also validates root node name */
#define virXMLParseStringCtxtRoot(xmlStr, url, rootnode, pctxt) \
- virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, rootnode, pctxt, NULL, false)
+ virXMLParseHelper(VIR_FROM_THIS, NULL, xmlStr, url, rootnode, pctxt, NULL, false, false)
/**
* virXMLParseFileCtxt:
@@ -252,7 +273,7 @@ virXMLPickShellSafeComment(const char *s
* Return the parsed document object, or NULL on failure.
*/
#define virXMLParseFileCtxt(filename, pctxt) \
- virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, NULL, pctxt, NULL, false)
+ virXMLParseHelper(VIR_FROM_THIS, filename, NULL, NULL, NULL, pctxt, NULL, false, false)
int
virXMLSaveFile(const char *path,