VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2024-12-25 16:09:10 +0100
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2024-12-25 16:09:10 +0100
commit283059523dd5d57f275390c0768417c00fc26adf (patch)
tree404fc8f6cba78da23cd2420cb3efac2c16839773 /src
parent650984c9581f3f2304d5f6d74addd4ac060ddca3 (diff)
downloadVeraCrypt-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.c80
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);