macOS: harden FUSE-T SMB metadata handling

Increase advertised metadata file size, broaden hdiutil path normalization, and make auxiliary device info updates atomic.
This commit is contained in:
Mounir IDRASSI
2026-04-22 10:55:14 +02:00
parent deb7f55bfb
commit 357ce6bd7a
3 changed files with 46 additions and 7 deletions

View File

@@ -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())
{

View File

@@ -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 <key>name</key><string>value</string> pairs.
string keyTag = "<key>" + key + "</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;
}

View File

@@ -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> 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)