Re: [PATCH] conf: Fix rawio/sgio checks for non-scsi hostdev devices

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On a Tuesday in 2024, Rayhan Faizel wrote:
The current hostdev parsing logic sets rawio or sgio even if the hostdev type
is not 'scsi'. The rawio field in virDomainHostdevSubsysSCSI overlaps with
wwpn field in virDomainHostdevSubsysSCSIVHost, consequently setting a bogus
pointer value such as 0x1 or 0x2 from virDomainHostdevSubsysSCSIVHost's
point of view. This leads to a segmentation fault when it attempts to free
wwpn.

While setting sgio does not appear to crash, it shares the same flawed logic
as setting rawio.

Instead, we test the presence of their xpaths along with the hostdev type
before setting either attributes. This patch also adds two test cases to
exercise both scenarios.

Signed-off-by: Rayhan Faizel <rayhan.faizel@xxxxxxxxx>

Fixes: 0fe2d8dd335054fae38b46bbbac58a4662e1a1d0

---
src/conf/domain_conf.c                        | 33 ++++++++-------
...scsi-vhost-rawio-invalid.x86_64-latest.err |  1 +
.../hostdev-scsi-vhost-rawio-invalid.xml      | 41 +++++++++++++++++++
...-scsi-vhost-sgio-invalid.x86_64-latest.err |  1 +
.../hostdev-scsi-vhost-sgio-invalid.xml       | 41 +++++++++++++++++++
tests/qemuxmlconftest.c                       |  2 +
6 files changed, 102 insertions(+), 17 deletions(-)
create mode 100644 tests/qemuxmlconfdata/hostdev-scsi-vhost-rawio-invalid.x86_64-latest.err
create mode 100644 tests/qemuxmlconfdata/hostdev-scsi-vhost-rawio-invalid.xml
create mode 100644 tests/qemuxmlconfdata/hostdev-scsi-vhost-sgio-invalid.x86_64-latest.err
create mode 100644 tests/qemuxmlconfdata/hostdev-scsi-vhost-sgio-invalid.xml

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 334152c4ff..5f8c6f2672 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -6220,7 +6220,6 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
    virDomainHostdevSubsysMediatedDev *mdevsrc = &def->source.subsys.u.mdev;
    virTristateBool managed;
    g_autofree char *model = NULL;
-    int rv;

    /* @managed can be read from the xml document - it is always an
     * attribute of the toplevel element, no matter what type of
@@ -6256,33 +6255,33 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
        return -1;
    }

-    if ((rv = virXMLPropEnum(node, "sgio",
-                             virDomainDeviceSGIOTypeFromString,
-                             VIR_XML_PROP_NONZERO,
-                             &scsisrc->sgio)) < 0) {
+    if (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI &&
+        virXPathBoolean("boolean(./@sgio)", txt)) {

Rather than accessing the attribute twice, can you use a temporary
variable to store the parsed enum value and only assign it if the subsys
type matches?

(Note that this attribute does nothing anymore and will be rejected by
validation later - we merely kept it in the parser and added the
validation error because otherwise already defined domains would
disappear)

+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("sgio is only supported for scsi host device"));
        return -1;
    }

-    if (rv > 0) {
-        if (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
-            virReportError(VIR_ERR_XML_ERROR, "%s",
-                           _("sgio is only supported for scsi host device"));
-            return -1;
-        }
-    }
-
-    if ((rv = virXMLPropTristateBool(node, "rawio",
-                                     VIR_XML_PROP_NONE,
-                                     &scsisrc->rawio)) < 0) {
+    if (virXMLPropEnum(node, "sgio",
+                       virDomainDeviceSGIOTypeFromString,
+                       VIR_XML_PROP_NONZERO,
+                       &scsisrc->sgio) < 0) {
        return -1;
    }

-    if (rv > 0 && def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
+    if (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI &&
+        virXPathBoolean("boolean(./@rawio)", ctxt)) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("rawio is only supported for scsi host device"));
        return -1;
    }

+    if (virXMLPropTristateBool(node, "rawio",
+                               VIR_XML_PROP_NONE,
+                               &scsisrc->rawio) < 0) {
+        return -1;

Same here.

Jano

+    }
+
    if (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV &&
        def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST) {
        if (model) {
diff --git a/tests/qemuxmlconfdata/hostdev-scsi-vhost-rawio-invalid.x86_64-latest.err b/tests/qemuxmlconfdata/hostdev-scsi-vhost-rawio-invalid.x86_64-latest.err
new file mode 100644
index 0000000000..ddaf449658
--- /dev/null
+++ b/tests/qemuxmlconfdata/hostdev-scsi-vhost-rawio-invalid.x86_64-latest.err
@@ -0,0 +1 @@
+XML error: rawio is only supported for scsi host device
diff --git a/tests/qemuxmlconfdata/hostdev-scsi-vhost-rawio-invalid.xml b/tests/qemuxmlconfdata/hostdev-scsi-vhost-rawio-invalid.xml
new file mode 100644
index 0000000000..80760ab941
--- /dev/null
+++ b/tests/qemuxmlconfdata/hostdev-scsi-vhost-rawio-invalid.xml
@@ -0,0 +1,41 @@
+<domain type='qemu'>
+  <name>QEMUGuest2</name>
+  <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest2'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='scsi' index='0' model='virtio-scsi'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </controller>
+    <controller type='usb' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+    </controller>
+    <controller type='ide' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <hostdev mode='subsystem' type='scsi_host' rawio='yes'>
+      <source protocol='vhost' wwpn='naa.5123456789abcde0'/>
+    </hostdev>
+    <memballoon model='virtio'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+    </memballoon>
+  </devices>
+</domain>
diff --git a/tests/qemuxmlconfdata/hostdev-scsi-vhost-sgio-invalid.x86_64-latest.err b/tests/qemuxmlconfdata/hostdev-scsi-vhost-sgio-invalid.x86_64-latest.err
new file mode 100644
index 0000000000..32256aad1c
--- /dev/null
+++ b/tests/qemuxmlconfdata/hostdev-scsi-vhost-sgio-invalid.x86_64-latest.err
@@ -0,0 +1 @@
+XML error: sgio is only supported for scsi host device
diff --git a/tests/qemuxmlconfdata/hostdev-scsi-vhost-sgio-invalid.xml b/tests/qemuxmlconfdata/hostdev-scsi-vhost-sgio-invalid.xml
new file mode 100644
index 0000000000..c549bddc1d
--- /dev/null
+++ b/tests/qemuxmlconfdata/hostdev-scsi-vhost-sgio-invalid.xml
@@ -0,0 +1,41 @@
+<domain type='qemu'>
+  <name>QEMUGuest2</name>
+  <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest2'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='scsi' index='0' model='virtio-scsi'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </controller>
+    <controller type='usb' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+    </controller>
+    <controller type='ide' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <hostdev mode='subsystem' type='scsi_host' sgio='filtered'>
+      <source protocol='vhost' wwpn='naa.5123456789abcde0'/>
+    </hostdev>
+    <memballoon model='virtio'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+    </memballoon>
+  </devices>
+</domain>
diff --git a/tests/qemuxmlconftest.c b/tests/qemuxmlconftest.c
index 8e0d47c6fd..1236ed5df1 100644
--- a/tests/qemuxmlconftest.c
+++ b/tests/qemuxmlconftest.c
@@ -2993,6 +2993,8 @@ mymain(void)
    DO_TEST_CAPS_LATEST("sound-device-virtio")

    DO_TEST_CAPS_LATEST_FAILURE("disk-network-iscsi-zero-hosts-invalid")
+    DO_TEST_CAPS_LATEST_PARSE_ERROR("hostdev-scsi-vhost-rawio-invalid")
+    DO_TEST_CAPS_LATEST_PARSE_ERROR("hostdev-scsi-vhost-sgio-invalid")

    /* check that all input files were actually used here */
    if (testConfXMLCheck(existingTestCases) < 0)
--
2.34.1

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux