[PATCH] esx: Don't crash when parsing unmounted datastore

Michal Privoznik via Devel posted 1 patch 6 days, 17 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/60a0d6308aecd469aadfd174ea28984bd64f580a.1787042929.git.mprivozn@redhat.com
src/esx/esx_driver.c | 3 +++
1 file changed, 3 insertions(+)
[PATCH] esx: Don't crash when parsing unmounted datastore
Posted by Michal Privoznik via Devel 6 days, 17 hours ago
From: Michal Privoznik <mprivozn@redhat.com>

When parsing disk source in ESX driver (esxParseVMXFileName())
the datastore is traversed through trying to find matching
prefix. But not every datastore has to be mounted. In that case,
esxVI_LookupDatastoreHostMount() returns success and the returned
struct has mountInfo->path set to NULL. This can be deducted from
the following backtrace (which shows that strlen() hidden in
STRSKIP() macro was given NULL pointer).

Thread 1 "virsh" received signal SIGSEGV, Segmentation fault.
__strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:76
76		VPCMPEQ	(%rdi), %ymm0, %ymm1
(gdb) bt full
#0  __strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:76
No locals.
#1  0x00007ffff7c292d7 in esxParseVMXFileName (fileName=0x5555557341d0 "/vmfs/volumes/5f64209f-c0af0aa8-70c4-e4434ba73190/msafra-RHEL9-shared-1/msafra-RHEL9-shared-1_1.vmdk", opaque=0x7fffffffcf80,
    out=0x7fffffffc738, allow_missing=false) at ../src/esx/esx_driver.c:172
        data = 0x7fffffffcf80
        propertyNameList = 0x555555738b50
        datastoreList = 0x55555573cf40
        datastore = <optimized out>
        hostMount = 0x555555733640
        datastoreName = 0x55555573e590 "mnecas-nfs-test"
        tmp = <optimized out>
        saveptr = 0x5555556a5b50 ""
        strippedFileName = 0x0
        copyOfFileName = 0x0
        directoryAndFileName = <optimized out>
        ret = -1
        __FUNCTION__ = "esxParseVMXFileName"
#2  0x00007ffff7bd47f4 in virVMXParseDisk (ctx=ctx@entry=0x7fffffffcfb0, xmlopt=xmlopt@entry=0x555555738d80, conf=conf@entry=0x5555556a5b50, device=device@entry=0, busType=<optimized out>, busType@entry=3,
    controllerOrBus=controllerOrBus@entry=1, unit=<optimized out>, def=0x7fffffffc960, vmdef=0x5555557375a0) at ../src/vmx/vmx.c:2553
        tmp = 0x0
        result = -1
        prefix = 0x5555557384d0 "scsi1:0"
        present_name = "scsi1:0.present", '\000' <repeats 16 times>
        present = true
        startConnected_name = "scsi1:0.startConnected\000\000\000\000\000\000\000\000\000"
        startConnected = true
        deviceType_name = "scsi1:0.deviceType", '\000' <repeats 13 times>
        deviceType = 0x555555737f60 "scsi-hardDisk"
        clientDevice_name = "scsi1:0.clientDevice", '\000' <repeats 11 times>
        clientDevice = false
        fileType_name = "scsi1:0.fileType", '\000' <repeats 15 times>
        fileType = 0x0
        fileName_name = "scsi1:0.fileName", '\000' <repeats 15 times>
        fileName = 0x5555557341d0 "/vmfs/volumes/5f64209f-c0af0aa8-70c4-e4434ba73190/msafra-RHEL9-shared-1/msafra-RHEL9-shared-1_1.vmdk"
        writeThrough_name = "scsi1:0.writeThrough", '\000' <repeats 11 times>
        writeThrough = false
        mode_name = "scsi1:0.mode", '\000' <repeats 19 times>
        mode = 0x0
        cleanup = <optimized out>
        __FUNCTION__ = "virVMXParseDisk"
#3  0x00007ffff7bd5f01 in virVMXParseConfig (ctx=0x7fffffffcfb0, xmlopt=0x555555738d80, caps=<optimized out>, vmx=<optimized out>) at ../src/vmx/vmx.c:1749
#4  0x00007ffff7c35319 in esxDomainGetXMLDesc (domain=<optimized out>, flags=0) at ../src/esx/esx_driver.c:2595
#5  0x00007ffff7cc4fd3 in virDomainGetXMLDesc (domain=domain@entry=0x5555557367f0, flags=flags@entry=0) at ../src/libvirt-domain.c:2898
#6  0x0000555555586cca in cmdDumpXML (ctl=0x7fffffffd1d0, cmd=0x5555556a5450) at ../tools/virsh-domain.c:10787
#7  0x00005555555bc7cb in vshCommandRun (ctl=0x7fffffffd1d0, cmd=0x5555556a5450) at ../tools/vsh.c:1383
#8  0x0000555555562fbc in main (argc=<optimized out>, argv=0x7fffffffd5c8) at ../tools/virsh.c:900

The backtrace was trimmed.

To fix this, just check whether mount path is not NULL before
passing it to STRSKIP().

Resolves: https://redhat.atlassian.net/browse/RHEL-213506
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---

BTW: this crasher is easily reproducible with our test suite too. Just
comment line 49 in tests/vmx2xmlmock.c file and run vmx2xmltest.

 src/esx/esx_driver.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index c5b3fa47b6..75bbd07750 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -169,6 +169,9 @@ esxParseVMXFileName(const char *fileName,
             goto cleanup;
         }
 
+        if (!hostMount->mountInfo->path)
+            continue;
+
         tmp = (char *)STRSKIP(fileName, hostMount->mountInfo->path);
 
         if (!tmp)
-- 
2.54.0
Re: [PATCH] esx: Don't crash when parsing unmounted datastore
Posted by Martin Kletzander via Devel 6 days, 16 hours ago
On Tue, Aug 18, 2026 at 10:50:08AM +0200, Michal Privoznik via Devel wrote:
>From: Michal Privoznik <mprivozn@redhat.com>
>
>When parsing disk source in ESX driver (esxParseVMXFileName())
>the datastore is traversed through trying to find matching
>prefix. But not every datastore has to be mounted. In that case,
>esxVI_LookupDatastoreHostMount() returns success and the returned
>struct has mountInfo->path set to NULL. This can be deducted from
>the following backtrace (which shows that strlen() hidden in
>STRSKIP() macro was given NULL pointer).
>
>The backtrace was trimmed.
>

Even more trimmed here.

>To fix this, just check whether mount path is not NULL before
>passing it to STRSKIP().
>
>Resolves: https://redhat.atlassian.net/browse/RHEL-213506
>Signed-off-by: Michal Privoznik <mprivozn@redhat.com>

Reviewed-by: Martin Kletzander <mkletzan@redhat.com>