Skip to content

Commit

Permalink
Don't use a global pointer to track loopback adapter
Browse files Browse the repository at this point in the history
Using a function allows us to ensure the filter module (open instance)
is in the running state, preventing sync problems between the WFP
loopback stuff and the NDIS LWF stuff. Problems may still exist, but
this ought to help.

Potentially fixes a crash, access violation in NPF_NetworkClassify, that
seems to be result of trying to lock the loopback adapter's open
instance when it is not running.
  • Loading branch information
bonsaiviking committed May 1, 2019
1 parent 4f352c8 commit 6847f0c
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 24 deletions.
14 changes: 7 additions & 7 deletions packetWin7/npf/npf/Loopback.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
//
// Global variables
//
extern POPEN_INSTANCE g_LoopbackOpenGroupHead; // Loopback adapter open_instance group head, this pointer points to one item in g_arrOpen list.
extern ULONG g_DltNullMode;

//
Expand Down Expand Up @@ -356,6 +355,7 @@ NPF_NetworkClassify(
#endif

{
POPEN_INSTANCE LoopbackOpen;
POPEN_INSTANCE GroupOpen;
POPEN_INSTANCE TempOpen;
NTSTATUS status = STATUS_SUCCESS;
Expand Down Expand Up @@ -605,13 +605,12 @@ NPF_NetworkClassify(
}

// Send the loopback packets data to the user-mode code.
// Can't assert this because a sleep could happen, detaching the adapter and making this pointer invalid.
//ASSERT(g_LoopbackOpenGroupHead);
if (g_LoopbackOpenGroupHead) {
LoopbackOpen = NPF_GetLoopbackOpen();
if (NPF_StartUsingBinding(LoopbackOpen)) {

/* Lock the group */
NdisAcquireSpinLock(&g_LoopbackOpenGroupHead->GroupLock);
GroupOpen = g_LoopbackOpenGroupHead->GroupNext;
NdisAcquireSpinLock(&LoopbackOpen->GroupLock);
GroupOpen = LoopbackOpen->GroupNext;
while (GroupOpen != NULL)
{
TempOpen = GroupOpen;
Expand All @@ -622,7 +621,8 @@ NPF_NetworkClassify(
}
GroupOpen = TempOpen->GroupNext;
}
NdisReleaseSpinLock(&g_LoopbackOpenGroupHead->GroupLock);
NdisReleaseSpinLock(&LoopbackOpen->GroupLock);
NPF_StopUsingBinding(LoopbackOpen);
}

Exit_Ethernet_Retreated:
Expand Down
47 changes: 32 additions & 15 deletions packetWin7/npf/npf/Openclos.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ ULONG g_NumOpenedInstances = 0;

extern POPEN_INSTANCE g_arrOpen; //Adapter OPEN_INSTANCE list head, each list item is a group head.
extern NDIS_SPIN_LOCK g_OpenArrayLock; //The lock for adapter OPEN_INSTANCE list.
extern POPEN_INSTANCE g_LoopbackOpenGroupHead; // Loopback adapter OPEN_INSTANCE group head, this pointer points to one item in g_arrOpen list.
//-------------------------------------------------------------------

BOOLEAN
Expand Down Expand Up @@ -1165,10 +1164,6 @@ NPF_RemoveFromOpenArray(
}
}

if (Open == g_LoopbackOpenGroupHead) {
g_LoopbackOpenGroupHead = NULL;
}

// Remove the links between group head and group members.
NdisAcquireSpinLock(&Open->GroupLock);
GroupOpen = Open->GroupNext;
Expand Down Expand Up @@ -1371,6 +1366,38 @@ NPF_GetOpenByAdapterName(

//-------------------------------------------------------------------

POPEN_INSTANCE
NPF_GetLoopbackOpen()
{
POPEN_INSTANCE CurOpen;
TRACE_ENTER();

NdisAcquireSpinLock(&g_OpenArrayLock);
for (CurOpen = g_arrOpen; CurOpen != NULL; CurOpen = CurOpen->Next)
{
if (NPF_StartUsingBinding(CurOpen) == FALSE)
{
continue;
}

if (CurOpen->Loopback)
{
NPF_StopUsingBinding(CurOpen);
NdisReleaseSpinLock(&g_OpenArrayLock);
return CurOpen;
}
else
{
NPF_StopUsingBinding(CurOpen);
}
}
NdisReleaseSpinLock(&g_OpenArrayLock);

TRACE_EXIT();
return NULL;
}

//-------------------------------------------------------------------
POPEN_INSTANCE
NPF_DuplicateOpenObject(
POPEN_INSTANCE OriginalOpen,
Expand Down Expand Up @@ -1728,9 +1755,7 @@ NPF_AttachAdapter(
if (RtlCompareMemory(g_LoopbackAdapterName.Buffer + devicePrefix.Length / 2, AttachParameters->BaseMiniportName->Buffer + devicePrefix.Length / 2,
AttachParameters->BaseMiniportName->Length - devicePrefix.Length) == AttachParameters->BaseMiniportName->Length - devicePrefix.Length)
{
ASSERT(g_LoopbackOpenGroupHead == NULL);
Open->Loopback = TRUE;
g_LoopbackOpenGroupHead = Open;
}
}
#endif
Expand Down Expand Up @@ -2027,14 +2052,6 @@ NOTE: Called at PASSIVE_LEVEL and the filter is in paused state

NPF_CloseBinding(Open);

#ifdef HAVE_WFP_LOOPBACK_SUPPORT
// "Npcap Loopback Adapter" is going to be detached, invalidate its global pointer as well.
if (Open->Loopback && Open == g_LoopbackOpenGroupHead)
{
g_LoopbackOpenGroupHead = NULL;
}
#endif

NPF_RemoveFromOpenArray(Open); // Must add this, if not, SYSTEM_SERVICE_EXCEPTION BSoD will occur.
NPF_ReleaseOpenInstanceResources(Open);
ExFreePool(Open);
Expand Down
1 change: 0 additions & 1 deletion packetWin7/npf/npf/Packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ NDIS_SPIN_LOCK g_OpenArrayLock; //The lock for adapter OPEN_INSTANCE list.
//
// Global variables used by WFP
//
POPEN_INSTANCE g_LoopbackOpenGroupHead = NULL; // Loopback adapter open_instance group head, this pointer points to one item in g_arrOpen list.
PDEVICE_OBJECT g_LoopbackDevObj = NULL;

NDIS_STRING g_LoopbackAdapterName;
Expand Down
6 changes: 6 additions & 0 deletions packetWin7/npf/npf/Packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,12 @@ NPF_GetOpenByAdapterName(
BOOLEAN Dot11
);

/*!
\brief Get the open instance for the loopback adapter
\return Pointer to the loopback filter module.
*/
POPEN_INSTANCE
NPF_GetLoopbackOpen();

/*!
\brief Get a copy of open instance from the global array.
Expand Down
2 changes: 1 addition & 1 deletion wpcap/libpcap

0 comments on commit 6847f0c

Please sign in to comment.