OpenBSD: fix device-hosted volume sizing

OpenBSD device length detection was returning the raw disk sector count from DIOCGPDINFO directly. That value is not bytes and it describes the physical/default disk label, which caused VeraCrypt to expose an incorrectly sized FUSE backing image through vnd for device-hosted volumes.

Use the current disklabel from DIOCGDINFO, derive the opened partition from the device minor number, and return the selected partition size in bytes. Keep the raw c partition on the whole-disk path by using DL_GETDSIZE there.

Also reject sector-misaligned device-hosted sizes during volume creation so new malformed OpenBSD device-hosted volumes are not created. Do not reject existing malformed headers at mount time, so users can still mount old OpenBSD-created volumes for recovery.

Refs #1589.

Refs #1593.
This commit is contained in:
Mounir IDRASSI
2026-05-25 22:31:20 +09:00
parent 0190270f9d
commit 5d7a2a78b8
2 changed files with 33 additions and 3 deletions

View File

@@ -282,6 +282,9 @@ namespace VeraCrypt
{
throw UnsupportedSectorSize (SRC_POS);
}
if (HostSize % options->SectorSize != 0)
throw ParameterIncorrect (SRC_POS);
}
else
options->SectorSize = TC_SECTOR_SIZE_FILE_HOSTED_VOLUME;

View File

@@ -125,7 +125,11 @@ namespace VeraCrypt
#elif defined (TC_OPENBSD)
struct disklabel dl;
throw_sys_sub_if (ioctl (FileHandle, DIOCGPDINFO, &dl) == -1, wstring (Path));
throw_sys_sub_if (ioctl (FileHandle, DIOCGDINFO, &dl) == -1, wstring (Path));
if (dl.d_secsize == 0)
throw ParameterIncorrect (SRC_POS);
return (uint32) dl.d_secsize;
#elif defined (TC_SOLARIS)
@@ -213,8 +217,31 @@ namespace VeraCrypt
return blockCount * blockSize;
# elif TC_OPENBSD
struct disklabel dl;
throw_sys_sub_if (ioctl (FileHandle, DIOCGPDINFO, &dl) == -1, wstring (Path));
return DL_GETDSIZE(&dl);
struct stat statData;
throw_sys_sub_if (ioctl (FileHandle, DIOCGDINFO, &dl) == -1, wstring (Path));
throw_sys_sub_if (fstat (FileHandle, &statData) == -1, wstring (Path));
if (dl.d_secsize == 0)
throw ParameterIncorrect (SRC_POS);
uint64 sectors;
int partition = DISKPART (statData.st_rdev);
if (partition == RAW_PART)
{
sectors = DL_GETDSIZE (&dl);
}
else
{
if (partition < 0 || partition >= dl.d_npartitions)
throw ParameterIncorrect (SRC_POS);
sectors = DL_GETPSIZE (&dl.d_partitions[partition]);
}
if (sectors > ((uint64) -1) / dl.d_secsize)
throw ParameterIncorrect (SRC_POS);
return sectors * dl.d_secsize;
# else
uint64 mediaSize;
throw_sys_sub_if (ioctl (FileHandle, DIOCGMEDIASIZE, &mediaSize) == -1, wstring (Path));