diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2024-12-25 16:09:10 +0100 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2024-12-25 16:09:10 +0100 |
commit | 283059523dd5d57f275390c0768417c00fc26adf (patch) | |
tree | 404fc8f6cba78da23cd2420cb3efac2c16839773 /src | |
parent | 650984c9581f3f2304d5f6d74addd4ac060ddca3 (diff) | |
download | VeraCrypt-283059523dd5d57f275390c0768417c00fc26adf.tar.gz VeraCrypt-283059523dd5d57f275390c0768417c00fc26adf.zip |
Windows Driver: make UpdateBuffer function more robust by adding security region size parameter
Diffstat (limited to 'src')
-rw-r--r-- | src/Driver/EncryptedIoQueue.c | 80 |
1 files changed, 60 insertions, 20 deletions
diff --git a/src/Driver/EncryptedIoQueue.c b/src/Driver/EncryptedIoQueue.c index 91399c47..de843339 100644 --- a/src/Driver/EncryptedIoQueue.c +++ b/src/Driver/EncryptedIoQueue.c @@ -224,41 +224,81 @@ static void ReleaseFragmentBuffer (EncryptedIoQueue *queue, uint8 *buffer) TC_BUG_CHECK (STATUS_INVALID_PARAMETER); } } -BOOL +BOOL UpdateBuffer( - uint8* buffer, - uint8* secRegion, - uint64 bufferDiskOffset, - uint32 bufferLength, - BOOL doUpadte - ) + uint8* buffer, + uint8* secRegion, + SIZE_T secRegionSize, + uint64 bufferDiskOffset, + uint32 bufferLength, + BOOL doUpadte +) { uint64 intersectStart; uint32 intersectLength; uint32 i; - DCS_DISK_ENTRY_LIST *DeList = (DCS_DISK_ENTRY_LIST*)(secRegion + 512); + DCS_DISK_ENTRY_LIST *DeList = NULL; BOOL updated = FALSE; - if (secRegion == NULL) return FALSE; + if (secRegion == NULL) + return FALSE; + + // Check if secRegion is large enough to hold the DCS_DISK_ENTRY_LIST structure + // starting at offset 512 + if (secRegionSize < (512 + sizeof(DCS_DISK_ENTRY_LIST))) + return FALSE; + + DeList = (DCS_DISK_ENTRY_LIST*)(secRegion + 512); + + // Ensure Count doesn't exceed the fixed array size + if (DeList->Count > 15) + return FALSE; + for (i = 0; i < DeList->Count; ++i) { if (DeList->DE[i].Type == DE_Sectors) { + uint64 sectorStart = DeList->DE[i].Sectors.Start; + uint64 sectorLength = DeList->DE[i].Sectors.Length; + uint64 sectorOffset = DeList->DE[i].Sectors.Offset; + + // Check that sectorOffset and sectorLength are valid within secRegion + if (sectorOffset > secRegionSize || + sectorLength == 0 || + (sectorOffset + sectorLength) > secRegionSize) + { + // Invalid entry - skip + continue; + } + GetIntersection( bufferDiskOffset, bufferLength, - DeList->DE[i].Sectors.Start, DeList->DE[i].Sectors.Start + DeList->DE[i].Sectors.Length - 1, + sectorStart, sectorStart + sectorLength - 1, &intersectStart, &intersectLength - ); + ); + if (intersectLength != 0) { + uint64 bufferPos = intersectStart - bufferDiskOffset; + uint64 regionPos = sectorOffset + (intersectStart - sectorStart); + + // Check buffer boundaries + if (bufferPos + intersectLength > bufferLength) + continue; // Intersection out of buffer range + + // Check secRegion boundaries + if (regionPos + intersectLength > secRegionSize) + continue; // Intersection out of secRegion range + updated = TRUE; - if(doUpadte && buffer != NULL) { -// Dump("Subst data\n"); + if (doUpadte && buffer != NULL) { memcpy( - buffer + (intersectStart - bufferDiskOffset), - secRegion + DeList->DE[i].Sectors.Offset + (intersectStart - DeList->DE[i].Sectors.Start), + buffer + bufferPos, + secRegion + regionPos, intersectLength - ); - } else { + ); + } + else { + // If no update is needed but intersection found return TRUE; } } } @@ -377,9 +417,9 @@ static VOID CompletionThreadProc(PVOID threadArg) } // 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); + UpdateBuffer(request->Data, queue->SecRegionData, queue->SecRegionSize, request->Offset.QuadPart, request->Length, TRUE); } if (request->CompleteOriginalIrp) { @@ -730,9 +770,9 @@ static VOID MainThreadProc (PVOID threadArg) } } // Update subst sectors if((queue->SecRegionData != NULL) && (queue->SecRegionSize > 512)) { - UpdateBuffer(buffer, queue->SecRegionData, alignedOffset.QuadPart, alignedLength, TRUE); + UpdateBuffer(buffer, queue->SecRegionData, queue->SecRegionSize, alignedOffset.QuadPart, alignedLength, TRUE); } memcpy (dataBuffer, buffer + (item->OriginalOffset.LowPart & (ENCRYPTION_DATA_UNIT_SIZE - 1)), item->OriginalLength); } @@ -823,9 +863,9 @@ static VOID MainThreadProc (PVOID threadArg) 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)) + && UpdateBuffer (NULL, queue->SecRegionData, queue->SecRegionSize, 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); |