diff --git a/src/Common/Format.c b/src/Common/Format.c index e1531c47..0fea5539 100644 --- a/src/Common/Format.c +++ b/src/Common/Format.c @@ -124,6 +124,10 @@ int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams) 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; } else diff --git a/src/Core/VolumeCreator.cpp b/src/Core/VolumeCreator.cpp index 2f18be1d..7a9d4e82 100644 --- a/src/Core/VolumeCreator.cpp +++ b/src/Core/VolumeCreator.cpp @@ -301,6 +301,10 @@ namespace VeraCrypt if (HostSize < TC_MIN_HIDDEN_VOLUME_HOST_SIZE) throw ParameterIncorrect (SRC_POS); + + if (HostSize <= TC_TOTAL_VOLUME_HEADERS_SIZE + || options->Size > HostSize - TC_TOTAL_VOLUME_HEADERS_SIZE) + throw ParameterIncorrect (SRC_POS); break; default: diff --git a/src/Main/Forms/VolumeCreationWizard.cpp b/src/Main/Forms/VolumeCreationWizard.cpp index 5b010f79..9f50d258 100644 --- a/src/Main/Forms/VolumeCreationWizard.cpp +++ b/src/Main/Forms/VolumeCreationWizard.cpp @@ -1519,8 +1519,15 @@ namespace VeraCrypt struct statvfs stat; if (statvfs(((string)outerVolumeMountPoint).c_str(), &stat) == 0) { - outerVolumeAvailableSpace = (uint64) stat.f_bsize * (uint64) stat.f_bavail; - outerVolumeAvailableSpaceValid = true; + uint64 blockSize = (uint64) stat.f_frsize; + if (blockSize == 0) + blockSize = (uint64) stat.f_bsize; + + if (blockSize != 0) + { + outerVolumeAvailableSpace = blockSize * (uint64) stat.f_bavail; + outerVolumeAvailableSpaceValid = true; + } } #endif Core->DismountVolume (MountedOuterVolume); @@ -1545,6 +1552,7 @@ namespace VeraCrypt #endif shared_ptr outerVolume = Core->OpenVolume (make_shared (SelectedVolumePath), true, Password, Pim, Kdf, Keyfiles, VolumeProtection::ReadOnly); + uint64 outerVolumeDataSize = outerVolume->GetSize(); try { MaxHiddenVolumeSize = Core->GetMaxHiddenVolumeSize (outerVolume); @@ -1555,17 +1563,24 @@ namespace VeraCrypt // estimate maximum hidden volume size as 80% of available size of outer volume if (outerVolumeAvailableSpaceValid) { - MaxHiddenVolumeSize =(4ULL * outerVolumeAvailableSpace) / 5ULL; + if (outerVolumeAvailableSpace > outerVolumeDataSize) + outerVolumeAvailableSpace = outerVolumeDataSize; + + MaxHiddenVolumeSize = (outerVolumeAvailableSpace / 5ULL) * 4ULL + + ((outerVolumeAvailableSpace % 5ULL) * 4ULL) / 5ULL; } else throw; } + if (MaxHiddenVolumeSize > outerVolumeDataSize) + MaxHiddenVolumeSize = outerVolumeDataSize; + // 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 // System Restore etc.) - uint64 reservedSize = outerVolume->GetSize() / 200; + uint64 reservedSize = outerVolumeDataSize / 200; if (reservedSize > 10 * BYTES_PER_MB) reservedSize = 10 * BYTES_PER_MB;