mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 02:58:02 -06:00
Windows driver: fix VERIFY/TRIM offset & validation, label handling, CPU group affinity, and cleanup
- Use local volumeOffset, correct IOCTL_DISK_VERIFY & TRIM range translation/validation - Enforce DataSetRangesLength alignment & per-range sanity checks - Add missing returns after PsTerminateSystemThread - Remove obsolete PsDereferenceImpersonationToken dynamic lookup - Correct wide string size usage & zero label info buffer - Fix DEBUG_TRACE macro check and GetCpuGroup off-by-one. proper affinity mask - Minor safety/clarity cleanups
This commit is contained in:
@@ -1344,11 +1344,14 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
|
|||||||
HRESULT hResult;
|
HRESULT hResult;
|
||||||
ULONGLONG ullStartingOffset, ullNewOffset, ullEndOffset;
|
ULONGLONG ullStartingOffset, ullNewOffset, ullEndOffset;
|
||||||
PVERIFY_INFORMATION pVerifyInformation;
|
PVERIFY_INFORMATION pVerifyInformation;
|
||||||
|
ULONGLONG volumeOffset = Extension->cryptoInfo->hiddenVolume
|
||||||
|
? Extension->cryptoInfo->hiddenVolumeOffset
|
||||||
|
: Extension->cryptoInfo->volDataAreaOffset;
|
||||||
pVerifyInformation = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
|
pVerifyInformation = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
ullStartingOffset = (ULONGLONG) pVerifyInformation->StartingOffset.QuadPart;
|
ullStartingOffset = (ULONGLONG) pVerifyInformation->StartingOffset.QuadPart;
|
||||||
hResult = ULongLongAdd(ullStartingOffset,
|
hResult = ULongLongAdd(ullStartingOffset,
|
||||||
(ULONGLONG) Extension->cryptoInfo->hiddenVolume ? Extension->cryptoInfo->hiddenVolumeOffset : Extension->cryptoInfo->volDataAreaOffset,
|
volumeOffset,
|
||||||
&ullNewOffset);
|
&ullNewOffset);
|
||||||
if (hResult != S_OK)
|
if (hResult != S_OK)
|
||||||
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||||
@@ -1640,7 +1643,14 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
|
|||||||
ULONG ulNewInputLength = 0;
|
ULONG ulNewInputLength = 0;
|
||||||
BOOL bForwardIoctl = FALSE;
|
BOOL bForwardIoctl = FALSE;
|
||||||
|
|
||||||
if (((ULONGLONG) inputLength) >= minSizeGeneric && ((ULONGLONG) inputLength) >= minSizedataSet && ((ULONGLONG) inputLength) >= minSizeParameter)
|
if ( (pInputAttrs->DataSetRangesLength > 0)
|
||||||
|
&& (pInputAttrs->DataSetRangesLength % sizeof(DEVICE_DATA_SET_RANGE) != 0) )
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (((ULONGLONG) inputLength) >= minSizeGeneric && ((ULONGLONG) inputLength) >= minSizedataSet && ((ULONGLONG) inputLength) >= minSizeParameter)
|
||||||
{
|
{
|
||||||
if (bEntireSet)
|
if (bEntireSet)
|
||||||
{
|
{
|
||||||
@@ -1665,10 +1675,12 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
|
|||||||
if (pNewSetAttrs)
|
if (pNewSetAttrs)
|
||||||
{
|
{
|
||||||
PDEVICE_DATA_SET_RANGE pRange = (PDEVICE_DATA_SET_RANGE) (((unsigned char*) pNewSetAttrs) + dwDataSetOffset);
|
PDEVICE_DATA_SET_RANGE pRange = (PDEVICE_DATA_SET_RANGE) (((unsigned char*) pNewSetAttrs) + dwDataSetOffset);
|
||||||
|
ULONGLONG volumeOffset = Extension->cryptoInfo->hiddenVolume
|
||||||
|
? Extension->cryptoInfo->hiddenVolumeOffset
|
||||||
|
: Extension->cryptoInfo->volDataAreaOffset;
|
||||||
memcpy (pNewSetAttrs, pInputAttrs, inputLength);
|
memcpy (pNewSetAttrs, pInputAttrs, inputLength);
|
||||||
|
|
||||||
pRange->StartingOffset = (ULONGLONG) Extension->cryptoInfo->hiddenVolume ? Extension->cryptoInfo->hiddenVolumeOffset : Extension->cryptoInfo->volDataAreaOffset;
|
pRange->StartingOffset = volumeOffset;
|
||||||
pRange->LengthInBytes = Extension->DiskLength;
|
pRange->LengthInBytes = Extension->DiskLength;
|
||||||
|
|
||||||
pNewSetAttrs->Size = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES);
|
pNewSetAttrs->Size = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES);
|
||||||
@@ -1713,25 +1725,39 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
|
|||||||
PDEVICE_DATA_SET_RANGE pNewRanges = (PDEVICE_DATA_SET_RANGE) (((unsigned char*) pNewSetAttrs) + pInputAttrs->DataSetRangesOffset);
|
PDEVICE_DATA_SET_RANGE pNewRanges = (PDEVICE_DATA_SET_RANGE) (((unsigned char*) pNewSetAttrs) + pInputAttrs->DataSetRangesOffset);
|
||||||
PDEVICE_DATA_SET_RANGE pInputRanges = (PDEVICE_DATA_SET_RANGE) (((unsigned char*) pInputAttrs) + pInputAttrs->DataSetRangesOffset);
|
PDEVICE_DATA_SET_RANGE pInputRanges = (PDEVICE_DATA_SET_RANGE) (((unsigned char*) pInputAttrs) + pInputAttrs->DataSetRangesOffset);
|
||||||
DWORD dwInputRangesCount = 0, dwNewRangesCount = 0, i;
|
DWORD dwInputRangesCount = 0, dwNewRangesCount = 0, i;
|
||||||
ULONGLONG ullStartingOffset, ullNewOffset, ullEndOffset;
|
ULONGLONG volumeOffset, ullStartingOffset, ullNewOffset, ullEndOffset;
|
||||||
HRESULT hResult;
|
HRESULT hResult;
|
||||||
|
|
||||||
memcpy (pNewSetAttrs, pInputAttrs, inputLength);
|
memcpy (pNewSetAttrs, pInputAttrs, inputLength);
|
||||||
|
|
||||||
dwInputRangesCount = pInputAttrs->DataSetRangesLength / sizeof(DEVICE_DATA_SET_RANGE);
|
dwInputRangesCount = pInputAttrs->DataSetRangesLength / sizeof(DEVICE_DATA_SET_RANGE);
|
||||||
|
|
||||||
|
volumeOffset = Extension->cryptoInfo->hiddenVolume ? Extension->cryptoInfo->hiddenVolumeOffset : Extension->cryptoInfo->volDataAreaOffset;
|
||||||
|
|
||||||
for (i = 0; i < dwInputRangesCount; i++)
|
for (i = 0; i < dwInputRangesCount; i++)
|
||||||
{
|
{
|
||||||
|
// Sanity check the input range
|
||||||
|
if ( pInputRanges[i].LengthInBytes == 0
|
||||||
|
|| (pInputRanges[i].LengthInBytes % Extension->BytesPerSector) != 0
|
||||||
|
|| (pInputRanges[i].StartingOffset % Extension->BytesPerSector) != 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ullStartingOffset = (ULONGLONG) pInputRanges[i].StartingOffset;
|
ullStartingOffset = (ULONGLONG) pInputRanges[i].StartingOffset;
|
||||||
|
|
||||||
|
// Validate that the range is within the virtual volume boundaries
|
||||||
|
hResult = ULongLongAdd(ullStartingOffset, (ULONGLONG) pInputRanges[i].LengthInBytes, &ullEndOffset);
|
||||||
|
if (hResult != S_OK || ullEndOffset > (ULONGLONG) Extension->DiskLength)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Translate the offset to the physical volume
|
||||||
hResult = ULongLongAdd(ullStartingOffset,
|
hResult = ULongLongAdd(ullStartingOffset,
|
||||||
(ULONGLONG) Extension->cryptoInfo->hiddenVolume ? Extension->cryptoInfo->hiddenVolumeOffset : Extension->cryptoInfo->volDataAreaOffset,
|
volumeOffset,
|
||||||
&ullNewOffset);
|
&ullNewOffset);
|
||||||
if (hResult != S_OK)
|
if (hResult != S_OK)
|
||||||
continue;
|
continue;
|
||||||
else if (S_OK != ULongLongAdd(ullStartingOffset, (ULONGLONG) pInputRanges[i].LengthInBytes, &ullEndOffset))
|
|
||||||
continue;
|
|
||||||
else if (ullEndOffset > (ULONGLONG) Extension->DiskLength)
|
|
||||||
continue;
|
|
||||||
else if (ullNewOffset > 0)
|
else if (ullNewOffset > 0)
|
||||||
{
|
{
|
||||||
pNewRanges[dwNewRangesCount].StartingOffset = (LONGLONG) ullNewOffset;
|
pNewRanges[dwNewRangesCount].StartingOffset = (LONGLONG) ullNewOffset;
|
||||||
@@ -1844,7 +1870,7 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
|
|||||||
return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0);
|
return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG) || defined (DEBG_TRACE)
|
#if defined(DEBUG) || defined (DEBUG_TRACE)
|
||||||
if (!NT_SUCCESS (Irp->IoStatus.Status))
|
if (!NT_SUCCESS (Irp->IoStatus.Status))
|
||||||
{
|
{
|
||||||
Dump ("IOCTL error 0x%08x (0x%x %d)\n",
|
Dump ("IOCTL error 0x%08x (0x%x %d)\n",
|
||||||
@@ -3058,6 +3084,7 @@ VOID VolumeThreadProc (PVOID Context)
|
|||||||
{
|
{
|
||||||
KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
|
KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
|
||||||
PsTerminateSystemThread (STATUS_SUCCESS);
|
PsTerminateSystemThread (STATUS_SUCCESS);
|
||||||
|
return; /* Make static analyzer happy */
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start IO queue
|
// Start IO queue
|
||||||
@@ -3097,6 +3124,7 @@ VOID VolumeThreadProc (PVOID Context)
|
|||||||
pThreadBlock->mount->nReturnCode = ERR_OS_ERROR;
|
pThreadBlock->mount->nReturnCode = ERR_OS_ERROR;
|
||||||
KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
|
KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
|
||||||
PsTerminateSystemThread (STATUS_SUCCESS);
|
PsTerminateSystemThread (STATUS_SUCCESS);
|
||||||
|
return; /* Make static analyzer happy */
|
||||||
}
|
}
|
||||||
|
|
||||||
KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
|
KeSetEvent (&Extension->keCreateEvent, 0, FALSE);
|
||||||
@@ -3134,6 +3162,7 @@ VOID VolumeThreadProc (PVOID Context)
|
|||||||
|
|
||||||
TCCloseVolume (DeviceObject, Extension);
|
TCCloseVolume (DeviceObject, Extension);
|
||||||
PsTerminateSystemThread (STATUS_SUCCESS);
|
PsTerminateSystemThread (STATUS_SUCCESS);
|
||||||
|
return; /* Make static analyzer happy */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3327,23 +3356,7 @@ void TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension)
|
|||||||
|
|
||||||
if (Extension->SecurityClientContextValid)
|
if (Extension->SecurityClientContextValid)
|
||||||
{
|
{
|
||||||
typedef VOID (*PsDereferenceImpersonationTokenDType) (PACCESS_TOKEN ImpersonationToken);
|
|
||||||
|
|
||||||
PsDereferenceImpersonationTokenDType PsDereferenceImpersonationTokenD;
|
|
||||||
UNICODE_STRING name;
|
|
||||||
RtlInitUnicodeString (&name, L"PsDereferenceImpersonationToken");
|
|
||||||
|
|
||||||
PsDereferenceImpersonationTokenD = (PsDereferenceImpersonationTokenDType) MmGetSystemRoutineAddress (&name);
|
|
||||||
if (!PsDereferenceImpersonationTokenD)
|
|
||||||
TC_BUG_CHECK (STATUS_NOT_IMPLEMENTED);
|
|
||||||
|
|
||||||
# define PsDereferencePrimaryToken
|
|
||||||
# define PsDereferenceImpersonationToken PsDereferenceImpersonationTokenD
|
|
||||||
|
|
||||||
SeDeleteClientSecurity (&Extension->SecurityClientContext);
|
SeDeleteClientSecurity (&Extension->SecurityClientContext);
|
||||||
|
|
||||||
# undef PsDereferencePrimaryToken
|
|
||||||
# undef PsDereferenceImpersonationToken
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualVolumeDeviceObjects[Extension->nDosDriveNo] = NULL;
|
VirtualVolumeDeviceObjects[Extension->nDosDriveNo] = NULL;
|
||||||
@@ -3833,10 +3846,13 @@ static NTSTATUS UpdateFsVolumeInformation (MOUNT_STRUCT* mount, PEXTENSION NewEx
|
|||||||
{
|
{
|
||||||
HANDLE volumeHandle;
|
HANDLE volumeHandle;
|
||||||
PFILE_OBJECT volumeFileObject;
|
PFILE_OBJECT volumeFileObject;
|
||||||
ULONG labelLen = (ULONG) wcslen (mount->wszLabel);
|
ULONG labelLen;
|
||||||
BOOL bIsNTFS = FALSE;
|
BOOL bIsNTFS = FALSE;
|
||||||
ULONG labelMaxLen, labelEffectiveLen;
|
ULONG labelMaxLen, labelEffectiveLen;
|
||||||
|
|
||||||
|
EnsureNullTerminatedString (mount->wszLabel, sizeof (mount->wszLabel));
|
||||||
|
labelLen = (ULONG) wcslen (mount->wszLabel);
|
||||||
|
|
||||||
if ((KeGetCurrentIrql() >= APC_LEVEL) || KeAreAllApcsDisabled())
|
if ((KeGetCurrentIrql() >= APC_LEVEL) || KeAreAllApcsDisabled())
|
||||||
{
|
{
|
||||||
UpdateFsVolumeInformationWorkItemArgs args;
|
UpdateFsVolumeInformationWorkItemArgs args;
|
||||||
@@ -3904,8 +3920,8 @@ static NTSTATUS UpdateFsVolumeInformation (MOUNT_STRUCT* mount, PEXTENSION NewEx
|
|||||||
labelEffectiveLen = labelLen > labelMaxLen? labelMaxLen : labelLen;
|
labelEffectiveLen = labelLen > labelMaxLen? labelMaxLen : labelLen;
|
||||||
|
|
||||||
// correct the label in the device
|
// correct the label in the device
|
||||||
memset (&NewExtension->wszLabel[labelEffectiveLen], 0, 33 - labelEffectiveLen);
|
memset (&NewExtension->wszLabel[labelEffectiveLen], 0, (33 - labelEffectiveLen) * sizeof (WCHAR));
|
||||||
memcpy (mount->wszLabel, NewExtension->wszLabel, 33);
|
memcpy (mount->wszLabel, NewExtension->wszLabel, 33 * sizeof (WCHAR));
|
||||||
|
|
||||||
// set the volume label
|
// set the volume label
|
||||||
__try
|
__try
|
||||||
@@ -3915,6 +3931,7 @@ static NTSTATUS UpdateFsVolumeInformation (MOUNT_STRUCT* mount, PEXTENSION NewEx
|
|||||||
FILE_FS_LABEL_INFORMATION* labelInfo = (FILE_FS_LABEL_INFORMATION*) TCalloc (labelInfoSize);
|
FILE_FS_LABEL_INFORMATION* labelInfo = (FILE_FS_LABEL_INFORMATION*) TCalloc (labelInfoSize);
|
||||||
if (labelInfo)
|
if (labelInfo)
|
||||||
{
|
{
|
||||||
|
RtlZeroMemory(labelInfo, labelInfoSize);
|
||||||
labelInfo->VolumeLabelLength = labelEffectiveLen * sizeof(WCHAR);
|
labelInfo->VolumeLabelLength = labelEffectiveLen * sizeof(WCHAR);
|
||||||
memcpy (labelInfo->VolumeLabel, mount->wszLabel, labelInfo->VolumeLabelLength);
|
memcpy (labelInfo->VolumeLabel, mount->wszLabel, labelInfo->VolumeLabelLength);
|
||||||
|
|
||||||
@@ -4420,7 +4437,7 @@ USHORT GetCpuGroup (size_t index)
|
|||||||
for (i = 0; i < groupCount; i++)
|
for (i = 0; i < groupCount; i++)
|
||||||
{
|
{
|
||||||
cpuCount += (size_t) KeQueryActiveProcessorCountEx (i);
|
cpuCount += (size_t) KeQueryActiveProcessorCountEx (i);
|
||||||
if (cpuCount >= index)
|
if (cpuCount > index)
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@@ -4431,10 +4448,15 @@ USHORT GetCpuGroup (size_t index)
|
|||||||
|
|
||||||
void SetThreadCpuGroupAffinity (USHORT index)
|
void SetThreadCpuGroupAffinity (USHORT index)
|
||||||
{
|
{
|
||||||
|
GROUP_AFFINITY oldAffinity;
|
||||||
GROUP_AFFINITY groupAffinity = {0};
|
GROUP_AFFINITY groupAffinity = {0};
|
||||||
groupAffinity.Mask = ~0ULL;
|
ULONG count = KeQueryActiveProcessorCountEx(index);
|
||||||
|
KAFFINITY mask = (count >= 64) ? ~0ULL : ((1ULL << count) - 1);
|
||||||
|
if (count == 0) return; // invalid group index: nothing to do
|
||||||
|
|
||||||
|
groupAffinity.Mask = mask;
|
||||||
groupAffinity.Group = index;
|
groupAffinity.Group = index;
|
||||||
KeSetSystemGroupAffinityThread (&groupAffinity, NULL);
|
KeSetSystemGroupAffinityThread (&groupAffinity, &oldAffinity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes)
|
void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes)
|
||||||
|
|||||||
Reference in New Issue
Block a user