From 357ce6bd7a6ffca336242248530f482dde660629 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Wed, 22 Apr 2026 10:55:14 +0200 Subject: [PATCH] macOS: harden FUSE-T SMB metadata handling Increase advertised metadata file size, broaden hdiutil path normalization, and make auxiliary device info updates atomic. --- src/Core/Unix/CoreUnix.cpp | 21 +++++++++++++++++++++ src/Core/Unix/MacOSX/CoreMacOSX.cpp | 21 ++++++++++++++++++--- src/Driver/Fuse/FuseService.cpp | 11 +++++++---- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/Core/Unix/CoreUnix.cpp b/src/Core/Unix/CoreUnix.cpp index 098e9cb4..86878627 100644 --- a/src/Core/Unix/CoreUnix.cpp +++ b/src/Core/Unix/CoreUnix.cpp @@ -828,6 +828,27 @@ namespace VeraCrypt if (mountedVolumes.size() == 1) { mountedVolume = mountedVolumes.front(); + if (!mountedVirtualDevice.IsEmpty()) + { + if (mountedVolume->VirtualDevice.IsEmpty()) + mountedVolume->VirtualDevice = mountedVirtualDevice; + + if (!options.NoFilesystem && mountedVolume->MountPoint.IsEmpty()) + { + for (int mountPointRetries = 20; mountPointRetries > 0; --mountPointRetries) + { + try + { + mountedVolume->MountPoint = GetDeviceMountPoint (mountedVirtualDevice); + if (!mountedVolume->MountPoint.IsEmpty()) + break; + } + catch (...) { } + + Thread::Sleep (500); + } + } + } } else if (!mountedVirtualDevice.IsEmpty()) { diff --git a/src/Core/Unix/MacOSX/CoreMacOSX.cpp b/src/Core/Unix/MacOSX/CoreMacOSX.cpp index 22883fda..a00e10e1 100644 --- a/src/Core/Unix/MacOSX/CoreMacOSX.cpp +++ b/src/Core/Unix/MacOSX/CoreMacOSX.cpp @@ -76,6 +76,7 @@ namespace VeraCrypt static bool ExtractPlistString (const string &xml, const string &key, size_t start, size_t limit, string &value, size_t *endPos = nullptr) { + // hdiutil currently emits simple namevalue pairs. string keyTag = "" + key + ""; size_t p = xml.find (keyTag, start); if (p == string::npos || p >= limit) @@ -117,7 +118,7 @@ namespace VeraCrypt normalized += *i; } - if (normalized.find ("/private/var/") == 0) + if (normalized.find ("/private/") == 0) normalized.erase (0, 8); return normalized; @@ -160,9 +161,9 @@ namespace VeraCrypt return DevicePath(); } - static bool AuxiliaryControlFileHasVirtualDevice (const DirectoryPath &auxMountPoint, const DevicePath &virtualDev) + static bool AuxiliaryControlFileHasVirtualDevice (const DirectoryPath &auxMountPoint, const DevicePath &virtualDev, int retryCount = 50) { - for (int t = 0; t < 50; ++t) + for (int t = 0; t < retryCount; ++t) { try { @@ -395,6 +396,7 @@ namespace VeraCrypt try { FuseService::SendAuxDeviceInfo (auxMountPoint, virtualDev); +#ifndef VC_MACOSX_FUSET if (!AuxiliaryControlFileHasVirtualDevice (auxMountPoint, virtualDev)) { stringstream logMessage; @@ -405,6 +407,7 @@ namespace VeraCrypt throw TimeOut (SRC_POS); } +#endif } catch (...) { @@ -421,6 +424,18 @@ namespace VeraCrypt throw; } +#ifdef VC_MACOSX_FUSET + if (!AuxiliaryControlFileHasVirtualDevice (auxMountPoint, virtualDev, 10)) + { + stringstream logMessage; + logMessage << "VeraCrypt auxiliary mount did not report hdiutil device after mount: " + << string (auxMountPoint) << FuseService::GetControlPath() + << ", expected " << string (virtualDev) + << "; continuing with hdiutil device"; + SystemLog::WriteError (logMessage.str()); + } +#endif + return virtualDev; } diff --git a/src/Driver/Fuse/FuseService.cpp b/src/Driver/Fuse/FuseService.cpp index bc3ea62d..578fbee8 100644 --- a/src/Driver/Fuse/FuseService.cpp +++ b/src/Driver/Fuse/FuseService.cpp @@ -62,6 +62,7 @@ namespace VeraCrypt static const ino_t VC_FUSE_INODE_CONTROL = 3; static const ino_t VC_FUSE_INODE_AUX_DEVICE_INFO = 4; static const uint64 VC_FUSE_BLOCK_SIZE = 4096; + static const uint64 VC_FUSE_METADATA_SIZE = 64 * 1024; static const uint64 VC_FUSE_STAT_BLOCK_SIZE = 512; static uint64 fuse_service_ceil_div (uint64 value, uint64 divisor) @@ -210,7 +211,7 @@ namespace VeraCrypt { statData->st_mode = S_IFREG | 0600; statData->st_nlink = 1; - statData->st_size = VC_FUSE_BLOCK_SIZE; + statData->st_size = VC_FUSE_METADATA_SIZE; statData->st_ino = VC_FUSE_INODE_AUX_DEVICE_INFO; fuse_service_set_stat_blocks (statData); } @@ -226,7 +227,7 @@ namespace VeraCrypt { statData->st_mode = S_IFREG | 0600; statData->st_nlink = 1; - statData->st_size = VC_FUSE_BLOCK_SIZE; + statData->st_size = VC_FUSE_METADATA_SIZE; statData->st_ino = VC_FUSE_INODE_CONTROL; fuse_service_set_stat_blocks (statData); } @@ -710,10 +711,12 @@ namespace VeraCrypt { shared_ptr stream (new MemoryStream (buffer)); Serializer sr (stream); + DevicePath virtualDevice = sr.DeserializeString ("VirtualDevice"); + DevicePath loopDevice = sr.DeserializeString ("LoopDevice"); ScopeLock lock (OpenVolumeInfoMutex); - OpenVolumeInfo.VirtualDevice = sr.DeserializeString ("VirtualDevice"); - OpenVolumeInfo.LoopDevice = sr.DeserializeString ("LoopDevice"); + OpenVolumeInfo.VirtualDevice = virtualDevice; + OpenVolumeInfo.LoopDevice = loopDevice; } void FuseService::SendAuxDeviceInfo (const DirectoryPath &fuseMountPoint, const DevicePath &virtualDevice, const DevicePath &loopDevice)