mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-06-10 06:46:59 -05:00
Fix hidden volume size estimate for exFAT outer volumes
On Unix and macOS, the hidden volume wizard estimates the available space for non-FAT outer filesystems using statvfs(). The previous calculation used f_bsize with f_bavail, which can overstate available bytes on macOS exFAT because f_bsize may be the preferred I/O size instead of the fragment size associated with the block counts. Use f_frsize when it is reported, fall back to f_bsize, and clamp the non-FAT estimate to the actual outer VeraCrypt data size before applying the existing 80% safety heuristic. Also harden hidden volume creation in both the cross-platform VolumeCreator path and the Windows/common formatting path by rejecting sizes that would exceed the hidden host data area and overlap volume header space. Fixes #1037
This commit is contained in:
@@ -124,6 +124,10 @@ int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams)
|
|||||||
|
|
||||||
if (volParams->hiddenVol)
|
if (volParams->hiddenVol)
|
||||||
{
|
{
|
||||||
|
if (volParams->hiddenVolHostSize <= TC_TOTAL_VOLUME_HEADERS_SIZE
|
||||||
|
|| volParams->size > volParams->hiddenVolHostSize - TC_TOTAL_VOLUME_HEADERS_SIZE)
|
||||||
|
return ERR_VOL_SIZE_WRONG;
|
||||||
|
|
||||||
dataOffset = volParams->hiddenVolHostSize - TC_VOLUME_HEADER_GROUP_SIZE - volParams->size;
|
dataOffset = volParams->hiddenVolHostSize - TC_VOLUME_HEADER_GROUP_SIZE - volParams->size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -301,6 +301,10 @@ namespace VeraCrypt
|
|||||||
|
|
||||||
if (HostSize < TC_MIN_HIDDEN_VOLUME_HOST_SIZE)
|
if (HostSize < TC_MIN_HIDDEN_VOLUME_HOST_SIZE)
|
||||||
throw ParameterIncorrect (SRC_POS);
|
throw ParameterIncorrect (SRC_POS);
|
||||||
|
|
||||||
|
if (HostSize <= TC_TOTAL_VOLUME_HEADERS_SIZE
|
||||||
|
|| options->Size > HostSize - TC_TOTAL_VOLUME_HEADERS_SIZE)
|
||||||
|
throw ParameterIncorrect (SRC_POS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -1519,8 +1519,15 @@ namespace VeraCrypt
|
|||||||
struct statvfs stat;
|
struct statvfs stat;
|
||||||
if (statvfs(((string)outerVolumeMountPoint).c_str(), &stat) == 0)
|
if (statvfs(((string)outerVolumeMountPoint).c_str(), &stat) == 0)
|
||||||
{
|
{
|
||||||
outerVolumeAvailableSpace = (uint64) stat.f_bsize * (uint64) stat.f_bavail;
|
uint64 blockSize = (uint64) stat.f_frsize;
|
||||||
outerVolumeAvailableSpaceValid = true;
|
if (blockSize == 0)
|
||||||
|
blockSize = (uint64) stat.f_bsize;
|
||||||
|
|
||||||
|
if (blockSize != 0)
|
||||||
|
{
|
||||||
|
outerVolumeAvailableSpace = blockSize * (uint64) stat.f_bavail;
|
||||||
|
outerVolumeAvailableSpaceValid = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Core->DismountVolume (MountedOuterVolume);
|
Core->DismountVolume (MountedOuterVolume);
|
||||||
@@ -1545,6 +1552,7 @@ namespace VeraCrypt
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
shared_ptr <Volume> outerVolume = Core->OpenVolume (make_shared <VolumePath> (SelectedVolumePath), true, Password, Pim, Kdf, Keyfiles, VolumeProtection::ReadOnly);
|
shared_ptr <Volume> outerVolume = Core->OpenVolume (make_shared <VolumePath> (SelectedVolumePath), true, Password, Pim, Kdf, Keyfiles, VolumeProtection::ReadOnly);
|
||||||
|
uint64 outerVolumeDataSize = outerVolume->GetSize();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MaxHiddenVolumeSize = Core->GetMaxHiddenVolumeSize (outerVolume);
|
MaxHiddenVolumeSize = Core->GetMaxHiddenVolumeSize (outerVolume);
|
||||||
@@ -1555,17 +1563,24 @@ namespace VeraCrypt
|
|||||||
// estimate maximum hidden volume size as 80% of available size of outer volume
|
// estimate maximum hidden volume size as 80% of available size of outer volume
|
||||||
if (outerVolumeAvailableSpaceValid)
|
if (outerVolumeAvailableSpaceValid)
|
||||||
{
|
{
|
||||||
MaxHiddenVolumeSize =(4ULL * outerVolumeAvailableSpace) / 5ULL;
|
if (outerVolumeAvailableSpace > outerVolumeDataSize)
|
||||||
|
outerVolumeAvailableSpace = outerVolumeDataSize;
|
||||||
|
|
||||||
|
MaxHiddenVolumeSize = (outerVolumeAvailableSpace / 5ULL) * 4ULL
|
||||||
|
+ ((outerVolumeAvailableSpace % 5ULL) * 4ULL) / 5ULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MaxHiddenVolumeSize > outerVolumeDataSize)
|
||||||
|
MaxHiddenVolumeSize = outerVolumeDataSize;
|
||||||
|
|
||||||
// Add a reserve (in case the user mounts the outer volume and creates new files
|
// Add a reserve (in case the user mounts the outer volume and creates new files
|
||||||
// on it by accident or OS writes some new data behind his or her back, such as
|
// on it by accident or OS writes some new data behind his or her back, such as
|
||||||
// System Restore etc.)
|
// System Restore etc.)
|
||||||
|
|
||||||
uint64 reservedSize = outerVolume->GetSize() / 200;
|
uint64 reservedSize = outerVolumeDataSize / 200;
|
||||||
if (reservedSize > 10 * BYTES_PER_MB)
|
if (reservedSize > 10 * BYTES_PER_MB)
|
||||||
reservedSize = 10 * BYTES_PER_MB;
|
reservedSize = 10 * BYTES_PER_MB;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user