Linux: don't detach the host device of a device-hosted volume

MountVolumeNative attaches a loop device only for a volume in a file,
but it recorded the volume path as the loop device in every case. For
a volume on a block device mounted with kernel cryptography, that is
the host device itself, so DismountVolume and EmergencyDismountVolume
ran losetup -d on it. A loop device that the user had attached, for
example to open a volume inside a disk image, was detached, or marked
for autoclear when emergency cleanup ran while the filesystem was
busy. On other devices, such as partitions, losetup failed and was
retried for about 1.2 seconds before the error was ignored. This code
comes from TrueCrypt 7.1a.

Record the loop device only when MountVolumeNative attached one, as
its error path already does. A volume mounted by an earlier version
keeps its FUSE service after an upgrade, and that service still
reports the host device, so the unmount functions also skip a loop
device that is the volume's own path. A loop device that VeraCrypt
attached is never the volume path.

Validated with console builds as root, for volumes on a loop device,
on a partition of a loop device attached with --partscan, and with
--emergency-unmount while the filesystem was busy: losetup no longer
runs, the loop device stays attached, and the partition case unmounts
in 0.18 s instead of 1.43 s. The same holds when these volumes are
mounted by 1.26.29 and unmounted by this build. Volumes in files and
nokernelcrypto mounts still detach the loop device that VeraCrypt
attached, also when mounting fails.
This commit is contained in:
Mounir IDRASSI committed 2026-10-04 10:35:30 +09:00
1 parent 425cea6c9c
commit a1dfce108d
2 files changed
+8 -2

No files matched your search

+4 -2
View File
@@ -306,7 +306,8 @@ namespace VeraCrypt
#endif
catch (NotApplicable &) { }
if (!mountedVolume->LoopDevice.IsEmpty())
// Earlier versions recorded the host device of a device-hosted volume mounted with Linux kernel cryptography as its loop device
if (!mountedVolume->LoopDevice.IsEmpty() && wstring (mountedVolume->LoopDevice) != wstring (mountedVolume->Path))
{
try
{
@@ -410,7 +411,8 @@ namespace VeraCrypt
firstException.reset (e.CloneNew());
}
if (!mountedVolume->LoopDevice.IsEmpty())
// Earlier versions recorded the host device of a device-hosted volume mounted with kernel cryptography as its loop device
if (!mountedVolume->LoopDevice.IsEmpty() && wstring (mountedVolume->LoopDevice) != wstring (mountedVolume->Path))
{
try
{
+4
View File
@@ -651,7 +651,11 @@ namespace VeraCrypt
filesystemMounted = true;
}
// Dismounting detaches the recorded loop device, so record only one attached above
if (loopDevAttached)
FuseService::SendAuxDeviceInfo (auxMountPoint, nativeDevPath, volumePath);
else
FuseService::SendAuxDeviceInfo (auxMountPoint, nativeDevPath);
}
catch (...)
{