From a7d8522fee17f09ba033077be50d72b0001d0ae2 Mon Sep 17 00:00:00 2001
From: Martin Kletzander <mkletzan@redhat.com>
Date: Thu, 6 Nov 2025 14:33:31 +0100
Subject: [PATCH 1/8] conf: Add virDomainDefIDsParseString

This function performs only parsing with the underlying
virDomainDefParseIDs() function to get needed metadata for any ACL
checks, but nothing else to avoid extraneous allocations and any
parser-induced DoS over ACL-forbidden connections.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
---
 src/conf/domain_conf.c   | 29 +++++++++++++++++++++++++++++
 src/conf/domain_conf.h   |  3 +++
 src/libvirt_private.syms |  1 +
 3 files changed, 33 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3a64a11b14..f84563b2af 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -20026,6 +20026,35 @@ virDomainDefParse(const char *xmlStr,
     return virDomainDefParseNode(ctxt, xmlopt, parseOpaque, flags);
 }
 
+virDomainDef *
+virDomainDefIDsParseString(const char *xmlStr,
+                           virDomainXMLOption *xmlopt,
+                           unsigned int flags)
+{
+    g_autoptr(virDomainDef) def = NULL;
+    g_autoptr(xmlDoc) xml = NULL;
+    g_autoptr(xmlXPathContext) ctxt = NULL;
+    bool uuid_generated = false;
+
+    xml = virXMLParseWithIndent(NULL, xmlStr, _("(domain_definition)"),
+                                "domain", &ctxt, "domain.rng", false);
+
+    if (!xml)
+        return NULL;
+
+    def = virDomainDefNew(xmlopt);
+    if (!def)
+        return NULL;
+
+    if (virDomainDefParseIDs(def, ctxt, flags, &uuid_generated) < 0)
+        return NULL;
+
+    if (uuid_generated)
+        memset(def->uuid, 0, VIR_UUID_BUFLEN);
+
+    return g_steal_pointer(&def);
+}
+
 virDomainDef *
 virDomainDefParseString(const char *xmlStr,
                         virDomainXMLOption *xmlopt,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index d70c2633a7..ccdcc3a47b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3811,6 +3811,9 @@ virDomainDiskDef *virDomainDiskDefParse(const char *xmlStr,
 virStorageSource *virDomainDiskDefParseSource(const char *xmlStr,
                                               virDomainXMLOption *xmlopt,
                                               unsigned int flags);
+virDomainDef * virDomainDefIDsParseString(const char *xmlStr,
+                                          virDomainXMLOption *xmlopt,
+                                          unsigned int flags);
 virDomainDef *virDomainDefParseString(const char *xmlStr,
                                       virDomainXMLOption *xmlopt,
                                       void *parseOpaque,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 6ab78d504b..6165a182c8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -351,6 +351,7 @@ virDomainDefHasUSB;
 virDomainDefHasVcpusOffline;
 virDomainDefHasVDPANet;
 virDomainDefHasVFIOHostdev;
+virDomainDefIDsParseString;
 virDomainDefLifecycleActionAllowed;
 virDomainDefMaybeAddController;
 virDomainDefMaybeAddInput;
-- 
2.50.1