VeraCrypt
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2019-12-09 18:57:02 +0100
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2019-12-09 18:59:27 +0100
commit5eaa204d83a1d9867094c14b4a35f310f27f6c65 (patch)
tree1df948d79ae5891a7bdfceba08a0bba477153b72
parent31c4fbfc12e8a2293e1c40c8007a2981bbac534d (diff)
downloadVeraCrypt-5eaa204d83a1d9867094c14b4a35f310f27f6c65.tar.gz
VeraCrypt-5eaa204d83a1d9867094c14b4a35f310f27f6c65.zip
Windows Driver: Reduce memory usage of IOCTL_DISK_VERIFY handler. Now we reader disk by chunks of at most 64 KiB. Fix https://github.com/veracrypt/VeraCrypt/issues/562.
-rw-r--r--src/Driver/Ntdriver.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c
index 1327c12a..8caf7bfa 100644
--- a/src/Driver/Ntdriver.c
+++ b/src/Driver/Ntdriver.c
@@ -1384,7 +1384,8 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
else
{
IO_STATUS_BLOCK ioStatus;
- PVOID buffer = TCalloc (max (pVerifyInformation->Length, PAGE_SIZE));
+ DWORD dwBuffersize = min (pVerifyInformation->Length, 16 * PAGE_SIZE);
+ PVOID buffer = TCalloc (dwBuffersize);
if (!buffer)
{
@@ -1392,14 +1393,29 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION
}
else
{
- LARGE_INTEGER offset = pVerifyInformation->StartingOffset;
+ LARGE_INTEGER offset;
+ DWORD dwRemainingBytes = pVerifyInformation->Length, dwReadCount;
offset.QuadPart = ullNewOffset;
- Irp->IoStatus.Status = ZwReadFile (Extension->hDeviceFile, NULL, NULL, NULL, &ioStatus, buffer, pVerifyInformation->Length, &offset, NULL);
- TCfree (buffer);
+ while (dwRemainingBytes)
+ {
+ dwReadCount = min (dwBuffersize, dwRemainingBytes);
+ Irp->IoStatus.Status = ZwReadFile (Extension->hDeviceFile, NULL, NULL, NULL, &ioStatus, buffer, dwReadCount, &offset, NULL);
- if (NT_SUCCESS (Irp->IoStatus.Status) && ioStatus.Information != pVerifyInformation->Length)
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ if (NT_SUCCESS (Irp->IoStatus.Status) && ioStatus.Information != dwReadCount)
+ {
+ Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+ else if (!NT_SUCCESS (Irp->IoStatus.Status))
+ break;
+
+ dwRemainingBytes -= dwReadCount;
+ offset.QuadPart += (ULONGLONG) dwReadCount;
+ }
+
+ burn (buffer, dwBuffersize);
+ TCfree (buffer);
}
}