mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
fixed apc leak :DDD
This commit is contained in:
parent
861c6d84f8
commit
48799fe6d9
5 changed files with 133 additions and 89 deletions
102
driver/driver.c
102
driver/driver.c
|
@ -33,13 +33,21 @@ unlock:
|
|||
KeReleaseGuardedMutex( &driver_config.lock );
|
||||
}
|
||||
|
||||
/*
|
||||
* No need to hold the lock here as it thread freeing the APCs will
|
||||
* already hold the configuration lock. We also dont want to release and
|
||||
* reclaim the lock before calling this function since we need to ensure
|
||||
* we hold the lock during the entire free process.
|
||||
*/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
FreeApcContextStructure(
|
||||
_Inout_ PAPC_CONTEXT_HEADER Context
|
||||
)
|
||||
{
|
||||
BOOLEAN result = FALSE;
|
||||
KeAcquireGuardedMutex( &driver_config.lock );
|
||||
|
||||
DEBUG_LOG( "All APCs executed, freeing context structure" );
|
||||
|
||||
for ( INT index = 0; index < 10; index++ )
|
||||
{
|
||||
|
@ -58,10 +66,99 @@ FreeApcContextStructure(
|
|||
}
|
||||
|
||||
unlock:
|
||||
KeReleaseGuardedMutex( &driver_config.lock );
|
||||
return result;
|
||||
}
|
||||
|
||||
VOID
|
||||
IncrementApcCount(
|
||||
_In_ LONG ContextId
|
||||
)
|
||||
{
|
||||
PAPC_CONTEXT_HEADER header = NULL;
|
||||
GetApcContext( &header, ContextId );
|
||||
|
||||
if ( !header )
|
||||
return;
|
||||
|
||||
KeAcquireGuardedMutex( &driver_config.lock );
|
||||
header->count += 1;
|
||||
KeReleaseGuardedMutex( &driver_config.lock );
|
||||
}
|
||||
|
||||
VOID
|
||||
FreeApcAndDecrementApcCount(
|
||||
_In_ PRKAPC Apc,
|
||||
_In_ LONG ContextId
|
||||
)
|
||||
{
|
||||
PAPC_CONTEXT_HEADER context = NULL;
|
||||
|
||||
ExFreePoolWithTag( Apc, POOL_TAG_APC );
|
||||
|
||||
GetApcContext( &context, ContextId );
|
||||
|
||||
if ( !context )
|
||||
goto end;
|
||||
|
||||
KeAcquireGuardedMutex( &driver_config.lock );
|
||||
|
||||
context->count -= 1;
|
||||
|
||||
switch ( ContextId )
|
||||
{
|
||||
case APC_CONTEXT_ID_STACKWALK:
|
||||
|
||||
if ( context->count > 0 )
|
||||
goto end;
|
||||
|
||||
PAPC_STACKWALK_CONTEXT stackwalk_context = ( PAPC_STACKWALK_CONTEXT )context;
|
||||
|
||||
FreeApcStackwalkApcContextInformation( stackwalk_context );
|
||||
FreeApcContextStructure( stackwalk_context );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
KeReleaseGuardedMutex( &driver_config.lock );
|
||||
}
|
||||
|
||||
//NTSTATUS
|
||||
//QueryActiveApcContextsForCompletion()
|
||||
//{
|
||||
// DEBUG_LOG( "Querying active apc contexts" );
|
||||
//
|
||||
// KeAcquireGuardedMutex( &driver_config.lock );
|
||||
//
|
||||
// for ( INT index = 0; index < 10; index++ )
|
||||
// {
|
||||
// PAPC_CONTEXT_HEADER entry = NULL;
|
||||
// GetApcContextByIndex( &entry, index );
|
||||
//
|
||||
// /* ensure we dont try to unlock a null entry */
|
||||
// if ( entry == NULL )
|
||||
// continue;
|
||||
//
|
||||
// DEBUG_LOG( "APC Context id: %lx", entry->context_id );
|
||||
// DEBUG_LOG( "Actice Apc Count: %i", entry->count );
|
||||
//
|
||||
// if ( entry->count > 0 )
|
||||
// goto end;
|
||||
//
|
||||
// switch ( entry->context_id )
|
||||
// {
|
||||
// case APC_CONTEXT_ID_STACKWALK:
|
||||
// FreeApcStackwalkApcContextInformation( entry );
|
||||
// FreeApcContextStructure( entry );
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//end:
|
||||
//
|
||||
// KeReleaseGuardedMutex( &driver_config.lock );
|
||||
// return STATUS_SUCCESS;
|
||||
//}
|
||||
|
||||
VOID
|
||||
InsertApcContext(
|
||||
_In_ PVOID Context
|
||||
|
@ -460,6 +557,7 @@ DriverUnload(
|
|||
)
|
||||
{
|
||||
//PsSetCreateProcessNotifyRoutine( ProcessCreateNotifyRoutine, TRUE );
|
||||
//QueryActiveApcContextsForCompletion();
|
||||
FreeAllApcContextStructures();
|
||||
CleanupDriverConfigOnUnload();
|
||||
IoDeleteDevice( DriverObject->DeviceObject );
|
||||
|
|
|
@ -112,8 +112,24 @@ GetApcContextByIndex(
|
|||
_In_ INT Index
|
||||
);
|
||||
|
||||
VOID
|
||||
IncrementApcCount(
|
||||
_In_ LONG ContextId
|
||||
);
|
||||
|
||||
VOID
|
||||
FreeApcAndDecrementApcCount(
|
||||
_In_ PRKAPC Apc,
|
||||
_In_ LONG ContextId
|
||||
);
|
||||
|
||||
VOID TerminateProtectedProcessOnViolation();
|
||||
|
||||
VOID ClearProcessConfigOnProcessTermination();
|
||||
|
||||
NTSTATUS
|
||||
QueryActiveApcContextForCompletion(
|
||||
_In_ LONG ContextId
|
||||
);
|
||||
|
||||
#endif
|
|
@ -124,11 +124,6 @@ NTSTATUS DeviceControl(
|
|||
|
||||
case IOCTL_HANDLE_REPORTS_IN_CALLBACK_QUEUE:
|
||||
|
||||
status = QueryActiveApcContextsForCompletion();
|
||||
|
||||
if ( !NT_SUCCESS( status ) )
|
||||
DEBUG_ERROR( "QueryActiveApcContextsForCompletion failed with status %x", status );
|
||||
|
||||
status = HandlePeriodicGlobalReportQueueQuery(Irp);
|
||||
|
||||
if ( !NT_SUCCESS( status ) )
|
||||
|
|
|
@ -902,27 +902,7 @@ ApcRundownRoutine(
|
|||
_In_ PRKAPC Apc
|
||||
)
|
||||
{
|
||||
//FreeApcAndStatusStructure( Apc, APC_CONTEXT_ID_STACKWALK );
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
FreeApcAndDecrementApcCount(
|
||||
_In_ PRKAPC Apc,
|
||||
_In_ LONG ContextId
|
||||
)
|
||||
{
|
||||
PAPC_CONTEXT_HEADER header = NULL;
|
||||
|
||||
ExFreePoolWithTag( Apc, POOL_TAG_APC );
|
||||
GetApcContext( &header, ContextId );
|
||||
|
||||
if ( !header )
|
||||
return;
|
||||
|
||||
KeAcquireGuardedMutex( &header->lock );
|
||||
header->count -= 1;
|
||||
KeReleaseGuardedMutex( &header->lock );
|
||||
FreeApcAndDecrementApcCount( Apc, APC_CONTEXT_ID_STACKWALK );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -951,7 +931,7 @@ ApcKernelRoutine(
|
|||
buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, 0x200, POOL_TAG_APC );
|
||||
|
||||
if ( !buffer )
|
||||
return;
|
||||
goto free;
|
||||
|
||||
frames_captured = RtlCaptureStackBackTrace(
|
||||
NULL,
|
||||
|
@ -986,7 +966,9 @@ ApcKernelRoutine(
|
|||
|
||||
free:
|
||||
|
||||
ExFreePoolWithTag( buffer, POOL_TAG_APC );
|
||||
if (buffer )
|
||||
ExFreePoolWithTag( buffer, POOL_TAG_APC );
|
||||
|
||||
FreeApcAndDecrementApcCount( Apc, APC_CONTEXT_ID_STACKWALK );
|
||||
}
|
||||
|
||||
|
@ -1004,23 +986,6 @@ ApcNormalRoutine(
|
|||
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
IncrementApcCount(
|
||||
_In_ LONG ContextId
|
||||
)
|
||||
{
|
||||
PAPC_CONTEXT_HEADER header = NULL;
|
||||
GetApcContext( &header, ContextId );
|
||||
|
||||
if ( !header )
|
||||
return;
|
||||
|
||||
KeAcquireGuardedMutex( &header->lock );
|
||||
header->count += 1;
|
||||
KeReleaseGuardedMutex( &header->lock );
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
ValidateThreadViaKernelApcCallback(
|
||||
|
@ -1035,6 +1000,8 @@ ValidateThreadViaKernelApcCallback(
|
|||
PKAPC apc = NULL;
|
||||
BOOLEAN apc_status;
|
||||
|
||||
HANDLE id = PsGetProcessId( Process );
|
||||
|
||||
/* we dont want to schedule an apc to threads owned by the kernel */
|
||||
if ( Process == PsInitialSystemProcess )
|
||||
return;
|
||||
|
@ -1109,8 +1076,6 @@ ValidateThreadsViaKernelApc()
|
|||
context->header.context_id = APC_CONTEXT_ID_STACKWALK;
|
||||
context->modules = ExAllocatePool2( POOL_FLAG_NON_PAGED, sizeof( SYSTEM_MODULES ), POOL_TAG_APC );
|
||||
|
||||
KeInitializeGuardedMutex( &context->header.lock );
|
||||
|
||||
if ( !context->modules )
|
||||
{
|
||||
ExFreePoolWithTag( context, POOL_TAG_APC );
|
||||
|
@ -1139,40 +1104,8 @@ FreeApcStackwalkApcContextInformation(
|
|||
_In_ PAPC_STACKWALK_CONTEXT Context
|
||||
)
|
||||
{
|
||||
if (Context->modules->address )
|
||||
ExFreePoolWithTag( Context->modules->address, SYSTEM_MODULES_POOL );
|
||||
if ( Context->modules )
|
||||
ExFreePoolWithTag( Context->modules, SYSTEM_MODULES_POOL );
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
QueryActiveApcContextsForCompletion()
|
||||
{
|
||||
for ( INT index = 0; index < 10; index++ )
|
||||
{
|
||||
PAPC_CONTEXT_HEADER entry = NULL;
|
||||
GetApcContextByIndex( &entry, index );
|
||||
|
||||
/* ensure we dont try to unlock a null entry */
|
||||
if ( entry == NULL )
|
||||
continue;
|
||||
|
||||
KeAcquireGuardedMutex( &entry->lock );
|
||||
|
||||
DEBUG_LOG( "APC Context id: %lx", entry->context_id );
|
||||
DEBUG_LOG( "Actice Apc Count: %i", entry->count );
|
||||
|
||||
if ( entry->count > 0 )
|
||||
goto unlock;
|
||||
|
||||
switch ( entry->context_id )
|
||||
{
|
||||
case APC_CONTEXT_ID_STACKWALK:
|
||||
FreeApcStackwalkApcContextInformation( entry);
|
||||
break;
|
||||
}
|
||||
|
||||
unlock:
|
||||
KeReleaseGuardedMutex( &entry->lock );
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
ExFreePoolWithTag( Context->modules, POOL_TAG_APC );
|
||||
}
|
|
@ -102,7 +102,6 @@ typedef struct _APC_CONTEXT_HEADER
|
|||
{
|
||||
LONG context_id;
|
||||
volatile INT count;
|
||||
KGUARDED_MUTEX lock;
|
||||
|
||||
}APC_CONTEXT_HEADER, * PAPC_CONTEXT_HEADER;
|
||||
|
||||
|
@ -130,13 +129,16 @@ NTSTATUS HandleNmiIOCTL(
|
|||
_In_ PIRP Irp
|
||||
);
|
||||
|
||||
VOID FreeApcContextStructure(
|
||||
_Inout_ PVOID Context
|
||||
BOOLEAN
|
||||
FreeApcContextStructure(
|
||||
_Inout_ PAPC_CONTEXT_HEADER Context
|
||||
);
|
||||
|
||||
NTSTATUS ValidateThreadsViaKernelApc();
|
||||
|
||||
NTSTATUS
|
||||
QueryActiveApcContextsForCompletion();
|
||||
VOID
|
||||
FreeApcStackwalkApcContextInformation(
|
||||
_In_ PAPC_STACKWALK_CONTEXT Context
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue