Skip to content

Commit a1dfce1

Browse files
committed
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.
1 parent 425cea6 commit a1dfce1

2 files changed

Lines changed: 9 additions & 3 deletions

File tree

‎src/Core/Unix/CoreUnix.cpp‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,8 @@ namespace VeraCrypt
306306
#endif
307307
catch (NotApplicable &) { }
308308

309-
if (!mountedVolume->LoopDevice.IsEmpty())
309+
// Earlier versions recorded the host device of a device-hosted volume mounted with Linux kernel cryptography as its loop device
310+
if (!mountedVolume->LoopDevice.IsEmpty() && wstring (mountedVolume->LoopDevice) != wstring (mountedVolume->Path))
310311
{
311312
try
312313
{
@@ -410,7 +411,8 @@ namespace VeraCrypt
410411
firstException.reset (e.CloneNew());
411412
}
412413

413-
if (!mountedVolume->LoopDevice.IsEmpty())
414+
// Earlier versions recorded the host device of a device-hosted volume mounted with kernel cryptography as its loop device
415+
if (!mountedVolume->LoopDevice.IsEmpty() && wstring (mountedVolume->LoopDevice) != wstring (mountedVolume->Path))
414416
{
415417
try
416418
{

‎src/Core/Unix/Linux/CoreLinux.cpp‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,11 @@ namespace VeraCrypt
651651
filesystemMounted = true;
652652
}
653653

654-
FuseService::SendAuxDeviceInfo (auxMountPoint, nativeDevPath, volumePath);
654+
// Dismounting detaches the recorded loop device, so record only one attached above
655+
if (loopDevAttached)
656+
FuseService::SendAuxDeviceInfo (auxMountPoint, nativeDevPath, volumePath);
657+
else
658+
FuseService::SendAuxDeviceInfo (auxMountPoint, nativeDevPath);
655659
}
656660
catch (...)
657661
{

0 commit comments

Comments
 (0)