VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Driver/EncryptedIoQueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Driver/EncryptedIoQueue.c')
-rw-r--r--src/Driver/EncryptedIoQueue.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/Driver/EncryptedIoQueue.c b/src/Driver/EncryptedIoQueue.c
index 029a42f5..7f50ec30 100644
--- a/src/Driver/EncryptedIoQueue.c
+++ b/src/Driver/EncryptedIoQueue.c
@@ -225,6 +225,47 @@ static void ReleaseFragmentBuffer (EncryptedIoQueue *queue, byte *buffer)
}
}
+BOOL
+UpdateBuffer(
+ byte* buffer,
+ byte* secRegion,
+ uint64 bufferDiskOffset,
+ uint32 bufferLength,
+ BOOL doUpadte
+ )
+{
+ uint64 intersectStart;
+ uint32 intersectLength;
+ uint32 i;
+ DCS_DISK_ENTRY_LIST *DeList = (DCS_DISK_ENTRY_LIST*)(secRegion + 512);
+ BOOL updated = FALSE;
+
+ if (secRegion == NULL) return FALSE;
+ for (i = 0; i < DeList->Count; ++i) {
+ if (DeList->DE[i].Type == DE_Sectors) {
+ GetIntersection(
+ bufferDiskOffset, bufferLength,
+ DeList->DE[i].Sectors.Start, DeList->DE[i].Sectors.Start + DeList->DE[i].Sectors.Length - 1,
+ &intersectStart, &intersectLength
+ );
+ if (intersectLength != 0) {
+ updated = TRUE;
+ if(doUpadte && buffer != NULL) {
+// Dump("Subst data\n");
+ memcpy(
+ buffer + (intersectStart - bufferDiskOffset),
+ secRegion + DeList->DE[i].Sectors.Offset + (intersectStart - DeList->DE[i].Sectors.Start),
+ intersectLength
+ );
+ } else {
+ return TRUE;
+ }
+ }
+ }
+ }
+ return updated;
+}
+
static VOID CompletionThreadProc (PVOID threadArg)
{
@@ -260,6 +301,11 @@ static VOID CompletionThreadProc (PVOID threadArg)
DecryptDataUnits (request->Data + request->EncryptedOffset, &dataUnit, request->EncryptedLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo);
}
+// Dump("Read sector %lld count %d\n", request->Offset.QuadPart >> 9, request->Length >> 9);
+ // Update subst sectors
+ if((queue->SecRegionData != NULL) && (queue->SecRegionSize > 512)) {
+ UpdateBuffer(request->Data, queue->SecRegionData, request->Offset.QuadPart, request->Length, TRUE);
+ }
if (request->CompleteOriginalIrp)
{
@@ -609,6 +655,10 @@ static VOID MainThreadProc (PVOID threadArg)
DecryptDataUnits (buffer + (intersectStart - alignedOffset.QuadPart), &dataUnit, intersectLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo);
}
}
+ // Update subst sectors
+ if((queue->SecRegionData != NULL) && (queue->SecRegionSize > 512)) {
+ UpdateBuffer(buffer, queue->SecRegionData, alignedOffset.QuadPart, alignedLength, TRUE);
+ }
memcpy (dataBuffer, buffer + (item->OriginalOffset.LowPart & (ENCRYPTION_DATA_UNIT_SIZE - 1)), item->OriginalLength);
}
@@ -697,6 +747,15 @@ static VOID MainThreadProc (PVOID threadArg)
Dump ("Preventing write to boot loader or host protected area\n");
CompleteOriginalIrp (item, STATUS_MEDIA_WRITE_PROTECTED, 0);
continue;
+ }
+ else if (item->Write
+ && (queue->SecRegionData != NULL) && (queue->SecRegionSize > 512)
+ && UpdateBuffer (NULL, queue->SecRegionData, item->OriginalOffset.QuadPart, (uint32)(item->OriginalOffset.QuadPart + item->OriginalLength - 1), FALSE))
+ {
+ // Prevent inappropriately designed software from damaging important data
+ Dump ("Preventing write to the system GPT area\n");
+ CompleteOriginalIrp (item, STATUS_MEDIA_WRITE_PROTECTED, 0);
+ continue;
}
dataBuffer = (PUCHAR) MmGetSystemAddressForMdlSafe (irp->MdlAddress, HighPagePriority);