]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
tests: cover line-break rejection in DNS TXT and SRV records
authorMichael Bommarito <michael.bommarito@gmail.com>
Fri, 10 Jul 2026 11:07:01 +0000 (07:07 -0400)
committerDaniel P. Berrangé <berrange@redhat.com>
Thu, 16 Jul 2026 12:04:45 +0000 (13:04 +0100)
Add negative tests that feed XML numeric character references for LF
(&#10;) and CR (&#13;) into the DNS TXT value and SRV domain/target
attributes, covering both the network XML parse path and the update
API. Literal newlines are insufficient because XML parsers normalize
raw attribute whitespace to spaces; the numeric references are what
survive to the configuration emitter.

CVE-2026-61477

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
tests/networkxml2xmlupdatein/dns-txt-record-newline.xml [new file with mode: 0644]
tests/networkxml2xmlupdatein/srv-record-target-newline.xml [new file with mode: 0644]
tests/networkxml2xmlupdatetest.c
tests/networkxmlconfdata/nat-network-dns-srv-record-domain-newline.xml [new file with mode: 0644]
tests/networkxmlconfdata/nat-network-dns-srv-record-target-newline.xml [new file with mode: 0644]
tests/networkxmlconfdata/nat-network-dns-txt-record-newline.xml [new file with mode: 0644]
tests/networkxmlconftest.c
tests/virschematest.c

diff --git a/tests/networkxml2xmlupdatein/dns-txt-record-newline.xml b/tests/networkxml2xmlupdatein/dns-txt-record-newline.xml
new file mode 100644 (file)
index 0000000..13ed040
--- /dev/null
@@ -0,0 +1 @@
+<txt name='example' value='example value&#10;dhcp-script=/tmp/payload'/>
diff --git a/tests/networkxml2xmlupdatein/srv-record-target-newline.xml b/tests/networkxml2xmlupdatein/srv-record-target-newline.xml
new file mode 100644 (file)
index 0000000..f29385d
--- /dev/null
@@ -0,0 +1 @@
+<srv service='ldap' protocol='tcp' target='server.example.com&#10;dhcp-script=/tmp/payload'/>
index b017922d9444f04a6531503321b3a1b0e80f7890..35fdfed0ec34da1e611d5bcedceb56519a1d706c 100644 (file)
@@ -288,6 +288,10 @@ mymain(void)
 
 
     section = VIR_NETWORK_SECTION_DNS_TXT;
+    DO_TEST_FAIL("insert-dns-txt-record-newline",
+                 "dns-txt-record-newline",
+                 "nat-network-dns-txt-record",
+                 VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST);
     DO_TEST("insert-dns-txt-record",
             "dns-txt-record-snowman",
             "nat-network-dns-txt-record",
@@ -311,6 +315,10 @@ mymain(void)
             "nat-network-dns-txt-record",
             "nat-network-dns-txt-modify-ok",
             VIR_NETWORK_UPDATE_COMMAND_MODIFY);
+    DO_TEST_FAIL("modify-dns-txt-record-newline",
+                 "dns-txt-record-newline",
+                 "nat-network-dns-txt-record",
+                 VIR_NETWORK_UPDATE_COMMAND_MODIFY);
     DO_TEST_FAIL("modify-missing-dns-txt-record",
             "dns-txt-record-modify-fail",
             "nat-network-dns-txt-record",
@@ -328,6 +336,10 @@ mymain(void)
             "nat-network",
             "nat-network-dns-srv-record",
             VIR_NETWORK_UPDATE_COMMAND_ADD_LAST);
+    DO_TEST_FAIL("append-srv-record-target-newline",
+                 "srv-record-target-newline",
+                 "nat-network",
+                 VIR_NETWORK_UPDATE_COMMAND_ADD_LAST);
     DO_TEST_FAIL("add-existing-dns-srv-record",
                  "srv-record",
                  "nat-network-dns-srv-record",
diff --git a/tests/networkxmlconfdata/nat-network-dns-srv-record-domain-newline.xml b/tests/networkxmlconfdata/nat-network-dns-srv-record-domain-newline.xml
new file mode 100644 (file)
index 0000000..2a1a5e4
--- /dev/null
@@ -0,0 +1,14 @@
+<network>
+  <name>default</name>
+  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+  <forward dev='eth1' mode='nat'/>
+  <bridge name='virbr0' stp='on' delay='0'/>
+  <dns>
+    <srv service='ldap' protocol='tcp' domain='example.com&#13;dhcp-script=/tmp/payload' target='server.example.com'/>
+  </dns>
+  <ip address='192.168.122.1' netmask='255.255.255.0'>
+    <dhcp>
+      <range start='192.168.122.2' end='192.168.122.254'/>
+    </dhcp>
+  </ip>
+</network>
diff --git a/tests/networkxmlconfdata/nat-network-dns-srv-record-target-newline.xml b/tests/networkxmlconfdata/nat-network-dns-srv-record-target-newline.xml
new file mode 100644 (file)
index 0000000..f3f722a
--- /dev/null
@@ -0,0 +1,14 @@
+<network>
+  <name>default</name>
+  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+  <forward dev='eth1' mode='nat'/>
+  <bridge name='virbr0' stp='on' delay='0'/>
+  <dns>
+    <srv service='ldap' protocol='tcp' domain='example.com' target='server.example.com&#10;dhcp-script=/tmp/payload'/>
+  </dns>
+  <ip address='192.168.122.1' netmask='255.255.255.0'>
+    <dhcp>
+      <range start='192.168.122.2' end='192.168.122.254'/>
+    </dhcp>
+  </ip>
+</network>
diff --git a/tests/networkxmlconfdata/nat-network-dns-txt-record-newline.xml b/tests/networkxmlconfdata/nat-network-dns-txt-record-newline.xml
new file mode 100644 (file)
index 0000000..02408a1
--- /dev/null
@@ -0,0 +1,14 @@
+<network>
+  <name>default</name>
+  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+  <forward dev='eth1' mode='nat'/>
+  <bridge name='virbr0' stp='on' delay='0'/>
+  <dns>
+    <txt name='example' value='example value&#10;dhcp-script=/tmp/payload'/>
+  </dns>
+  <ip address='192.168.122.1' netmask='255.255.255.0'>
+    <dhcp>
+      <range start='192.168.122.2' end='192.168.122.254'/>
+    </dhcp>
+  </ip>
+</network>
index 40eb3ffdb4f1cbe0dce186263e33ef0af37a2e71..c0d3886a698912edfa72cea7635f6e55f261ac07 100644 (file)
@@ -323,7 +323,10 @@ mymain(void)
     DO_TEST("netboot-proxy-network");
     DO_TEST("netboot-tftp");
     DO_TEST("nat-network-dns-txt-record");
+    DO_TEST_PARSE_ERROR("nat-network-dns-txt-record-newline");
     DO_TEST("nat-network-dns-srv-record");
+    DO_TEST_PARSE_ERROR("nat-network-dns-srv-record-domain-newline");
+    DO_TEST_PARSE_ERROR("nat-network-dns-srv-record-target-newline");
     DO_TEST("nat-network-dns-srv-records");
     DO_TEST("nat-network-dns-srv-record-minimal");
     DO_TEST("nat-network-dns-hosts");
index 4faac8d9768d28da7e4563f3a5ee5b55a0abc218..fabe45b65d62e74fbe1db4ee6e8d94a8f5d16b95 100644 (file)
@@ -301,9 +301,18 @@ static const struct testSchemaEntry schemaInterface[] = {
     { .dir = "tests/interfaceschemadata" },
 };
 
+/* skip tests with completely broken XML */
+static const char *skip_networkxmlconfdata[] = {
+    "nat-network-dns-srv-record-domain-newline.xml",
+    "nat-network-dns-srv-record-target-newline.xml",
+    "nat-network-dns-txt-recor-record-newline.xml",
+    NULL,
+};
+
 static const struct testSchemaEntry schemaNetwork[] = {
     { .dir = "src/network" },
-    { .dir = "tests/networkxmlconfdata" },
+    { .dir = "tests/networkxmlconfdata",
+      .skip = skip_networkxmlconfdata },
     { .dir = "examples/xml/test/",
       .dirRegex = "testnet.*" },
     { .dir = "tests/networkxml2xmlupdateout" },