Skip to content

Commit

Permalink
fix toctou in vm read path (#1391)
Browse files Browse the repository at this point in the history
  • Loading branch information
jxy-s authored Sep 24, 2022
1 parent b66458b commit 16f717c
Showing 1 changed file with 45 additions and 7 deletions.
52 changes: 45 additions & 7 deletions KSystemInformer/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/

#include <kph.h>
#include <dyndata.h>

#include <trace.h>

Expand Down Expand Up @@ -356,13 +357,18 @@ NTSTATUS KphReadVirtualMemoryUnsafe(
{
NTSTATUS status;
PEPROCESS process;
SIZE_T numberOfBytesRead = 0;
SIZE_T numberOfBytesRead;
BOOLEAN releaseModuleLock;

PAGED_PASSIVE();

numberOfBytesRead = 0;
releaseModuleLock = FALSE;

if (!Buffer)
{
return STATUS_INVALID_PARAMETER_3;
status = STATUS_INVALID_PARAMETER_3;
goto Exit;
}

if (AccessMode != KernelMode)
Expand All @@ -371,7 +377,8 @@ NTSTATUS KphReadVirtualMemoryUnsafe(
(Add2Ptr(Buffer, BufferSize) < Buffer) ||
(Add2Ptr(Buffer, BufferSize) > MmHighestUserAddress))
{
return STATUS_ACCESS_VIOLATION;
status = STATUS_ACCESS_VIOLATION;
goto Exit;
}

if (NumberOfBytesRead)
Expand All @@ -382,7 +389,8 @@ NTSTATUS KphReadVirtualMemoryUnsafe(
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return GetExceptionCode();
status = GetExceptionCode();
goto Exit;
}
}
}
Expand All @@ -397,12 +405,32 @@ NTSTATUS KphReadVirtualMemoryUnsafe(
ULONG_PTR page;
ULONG_PTR pageEnd;

if (KphDynPsLoadedModuleResource)
{
//
// Prevent TOCTOU between checking the system module list and
// copying memory.
//
if (!ExAcquireResourceSharedLite(KphDynPsLoadedModuleResource,
TRUE))
{
KphTracePrint(TRACE_LEVEL_ERROR,
GENERAL,
"Failed to acquire PsLoadedModuleResource");

status = STATUS_RESOURCE_NOT_OWNED;
goto Exit;
}

releaseModuleLock = TRUE;
}

status = KphValidateAddressForSystemModules(BaseAddress,
BufferSize);

if (!NT_SUCCESS(status))
{
return status;
goto Exit;
}

//
Expand All @@ -426,7 +454,8 @@ NTSTATUS KphReadVirtualMemoryUnsafe(
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return GetExceptionCode();
status = GetExceptionCode();
goto Exit;
}

numberOfBytesRead = BufferSize;
Expand All @@ -440,7 +469,8 @@ NTSTATUS KphReadVirtualMemoryUnsafe(

if (!ProcessHandle)
{
return STATUS_INVALID_PARAMETER_1;
status = STATUS_INVALID_PARAMETER_1;
goto Exit;
}

status = ObReferenceObjectByHandle(ProcessHandle,
Expand Down Expand Up @@ -468,6 +498,14 @@ NTSTATUS KphReadVirtualMemoryUnsafe(
status = STATUS_SUCCESS;
}

Exit:

if (releaseModuleLock)
{
NT_ASSERT(KphDynPsLoadedModuleResource);
ExReleaseResourceLite(KphDynPsLoadedModuleResource);
}

if (NumberOfBytesRead)
{
if (AccessMode != KernelMode)
Expand Down

0 comments on commit 16f717c

Please sign in to comment.