Windows Driver: Potential memory corruption caused by integer overflow in IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES (reported by I.V. Sprundel)

This commit is contained in:
Mounir IDRASSI 2021-08-24 09:27:48 +02:00
parent f462160542
commit 09206053d5
No known key found for this signature in database
GPG Key ID: 02C30AE90FAE4A6F

View File

@ -154,6 +154,29 @@ ULONG ExDefaultMdlProtection = 0;
PDEVICE_OBJECT VirtualVolumeDeviceObjects[MAX_MOUNTED_VOLUME_DRIVE_NUMBER + 1]; PDEVICE_OBJECT VirtualVolumeDeviceObjects[MAX_MOUNTED_VOLUME_DRIVE_NUMBER + 1];
BOOL AlignValue (ULONG ulValue, ULONG ulAlignment, ULONG *pulResult)
{
BOOL bRet = FALSE;
HRESULT hr;
if (ulAlignment == 0)
{
*pulResult = ulValue;
bRet = TRUE;
}
else
{
ulAlignment -= 1;
hr = ULongAdd (ulValue, ulAlignment, &ulValue);
if (S_OK == hr)
{
*pulResult = ulValue & (~ulAlignment);
bRet = TRUE;
}
}
return bRet;
}
BOOL IsUefiBoot () BOOL IsUefiBoot ()
{ {
BOOL bStatus = FALSE; BOOL bStatus = FALSE;
@ -1690,7 +1713,7 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
ULONG ulNewInputLength = 0; ULONG ulNewInputLength = 0;
BOOL bForwardIoctl = FALSE; BOOL bForwardIoctl = FALSE;
if (inputLength >= minSizeGeneric && inputLength >= minSizedataSet && inputLength >= minSizeParameter) if (((ULONGLONG) inputLength) >= minSizeGeneric && ((ULONGLONG) inputLength) >= minSizedataSet && ((ULONGLONG) inputLength) >= minSizeParameter)
{ {
if (bEntireSet) if (bEntireSet)
{ {
@ -1702,12 +1725,15 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
} }
else else
{ {
DWORD dwDataSetOffset = ALIGN_VALUE (inputLength, sizeof(DEVICE_DATA_SET_RANGE)); DWORD dwDataSetOffset;
DWORD dwDataSetLength = sizeof(DEVICE_DATA_SET_RANGE); DWORD dwDataSetLength = sizeof(DEVICE_DATA_SET_RANGE);
if (AlignValue (inputLength, sizeof(DEVICE_DATA_SET_RANGE), &dwDataSetOffset))
{
Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE set. Setting data range to all volume.\n"); Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE set. Setting data range to all volume.\n");
ulNewInputLength = dwDataSetOffset + dwDataSetLength; if (S_OK == ULongAdd(dwDataSetOffset, dwDataSetLength, &ulNewInputLength))
{
pNewSetAttrs = (PDEVICE_MANAGE_DATA_SET_ATTRIBUTES) TCalloc (ulNewInputLength); pNewSetAttrs = (PDEVICE_MANAGE_DATA_SET_ATTRIBUTES) TCalloc (ulNewInputLength);
if (pNewSetAttrs) if (pNewSetAttrs)
{ {
@ -1735,6 +1761,20 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
} }
} }
else
{
Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE set but data range length computation overflowed.\n");
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
}
}
else
{
Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE set but data set offset computation overflowed.\n");
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
}
}
} }
else else
{ {