Skip to content

Commit

Permalink
Unset global Loopback Open pointer when loopback adapter is unloaded.…
Browse files Browse the repository at this point in the history
… nmap/nmap#721
  • Loading branch information
bonsaiviking committed Mar 2, 2017
1 parent 0fcd07d commit 09bbc7a
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 147 deletions.
53 changes: 28 additions & 25 deletions packetWin7/npf/npf/Loopback.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,36 +605,39 @@ NPF_NetworkClassify(
}

// Send the loopback packets data to the user-mode code.
ASSERT(g_LoopbackOpenGroupHead);

/* Lock the group */
NdisAcquireSpinLock(&g_LoopbackOpenGroupHead->GroupLock);
/* Grab a local pointer to the copy we're using */
TempArray = g_LoopbackOpenGroupHead->Group;
/* Double-check there is even a group here */
if (TempArray) {
/* Increment the refcount on this so nobody frees it while we're iterating */
TempArray->refcount++;
/* Release the lock, allow others to replace the list if necessary */
NdisReleaseSpinLock(&g_LoopbackOpenGroupHead->GroupLock);
// Can't assert this because a sleep could happen, detaching the adapter and making this pointer invalid.
//ASSERT(g_LoopbackOpenGroupHead);
if (g_LoopbackOpenGroupHead) {

for (unsigned int i=0; i < TempArray->length; i++) {
TempOpen = TempArray->array[i];
if (TempOpen->AdapterBindingStatus == ADAPTER_BOUND)
{
NPF_TapExForEachOpen(TempOpen, pClonedNetBufferList);
/* Lock the group */
NdisAcquireSpinLock(&g_LoopbackOpenGroupHead->GroupLock);
/* Grab a local pointer to the copy we're using */
TempArray = g_LoopbackOpenGroupHead->Group;
/* Double-check there is even a group here */
if (TempArray) {
/* Increment the refcount on this so nobody frees it while we're iterating */
TempArray->refcount++;
/* Release the lock, allow others to replace the list if necessary */
NdisReleaseSpinLock(&g_LoopbackOpenGroupHead->GroupLock);

for (unsigned int i=0; i < TempArray->length; i++) {
TempOpen = TempArray->array[i];
if (TempOpen->AdapterBindingStatus == ADAPTER_BOUND)
{
NPF_TapExForEachOpen(TempOpen, pClonedNetBufferList);
}
}
}

/* Reacquire the lock to make sure nobody mucks with refcount after we check it */
NdisAcquireSpinLock(&g_LoopbackOpenGroupHead->GroupLock);
/* Decrement the refcount and check if we were the last ones using this copy */
if (--TempArray->refcount == 0) {
ExFreePool(TempArray);
/* Reacquire the lock to make sure nobody mucks with refcount after we check it */
NdisAcquireSpinLock(&g_LoopbackOpenGroupHead->GroupLock);
/* Decrement the refcount and check if we were the last ones using this copy */
if (--TempArray->refcount == 0) {
ExFreePool(TempArray);
}
}
/* Release the spin lock no matter what. */
NdisReleaseSpinLock(&g_LoopbackOpenGroupHead->GroupLock);
}
/* Release the spin lock no matter what. */
NdisReleaseSpinLock(&g_LoopbackOpenGroupHead->GroupLock);

Exit_Ethernet_Retreated:
// Advance the offset back to the original position.
Expand Down
248 changes: 126 additions & 122 deletions packetWin7/npf/npf/Openclos.c
Original file line number Diff line number Diff line change
Expand Up @@ -1036,45 +1036,45 @@ NPF_AddToGroupOpenArray(
POPEN_INSTANCE GroupHead
)
{
OPEN_ARRAY *tempArray = NULL;
unsigned int newLen = 1;
OPEN_ARRAY *tempArray = NULL;
unsigned int newLen = 1;

TRACE_ENTER();

NdisAcquireSpinLock(&GroupHead->GroupLock);

if (GroupHead->Group) {
newLen = GroupHead->Group->length + 1;
NdisAcquireSpinLock(&GroupHead->GroupLock);

if (GroupHead->Group) {
newLen = GroupHead->Group->length + 1;
}
Open->GroupHead = GroupHead;

/* Make a new OPEN_ARRAY with room for all the current Opens plus the new one */
tempArray = ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_ARRAY) + newLen * sizeof(OPEN_INSTANCE *), 'PAOG');
if (tempArray == NULL) {
// no memory
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Failed to allocate memory pool");
NdisReleaseSpinLock(&GroupHead->GroupLock);
TRACE_EXIT();
return;
}

/* Copy over the old array */
if (GroupHead->Group) {
RtlCopyMemory(tempArray->array, GroupHead->Group->array, (GroupHead->Group->length) * sizeof(OPEN_INSTANCE *));
/* If we're the last ones using the old copy, free it */
if (--GroupHead->Group->refcount == 0) {
ExFreePool(GroupHead->Group);
}
}

/* Assign the new Open to the last slot in the array */
tempArray->array[newLen - 1] = Open;
/* Initialize length and refcount and swap in */
tempArray->length = newLen;
tempArray->refcount = 1;
GroupHead->Group = tempArray;

NdisReleaseSpinLock(&GroupHead->GroupLock);

/* Make a new OPEN_ARRAY with room for all the current Opens plus the new one */
tempArray = ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_ARRAY) + newLen * sizeof(OPEN_INSTANCE *), 'PAOG');
if (tempArray == NULL) {
// no memory
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Failed to allocate memory pool");
NdisReleaseSpinLock(&GroupHead->GroupLock);
TRACE_EXIT();
return;
}

/* Copy over the old array */
if (GroupHead->Group) {
RtlCopyMemory(tempArray->array, GroupHead->Group->array, (GroupHead->Group->length) * sizeof(OPEN_INSTANCE *));
/* If we're the last ones using the old copy, free it */
if (--GroupHead->Group->refcount == 0) {
ExFreePool(GroupHead->Group);
}
}

/* Assign the new Open to the last slot in the array */
tempArray->array[newLen - 1] = Open;
/* Initialize length and refcount and swap in */
tempArray->length = newLen;
tempArray->refcount = 1;
GroupHead->Group = tempArray;

NdisReleaseSpinLock(&GroupHead->GroupLock);

TRACE_EXIT();
}
Expand Down Expand Up @@ -1119,17 +1119,21 @@ NPF_RemoveFromOpenArray(
}
}

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

// Remove the links between group head and group members.
NdisAcquireSpinLock(&Open->GroupLock);
if (Open->Group) {
for (unsigned int i=0; i < Open->Group->length; i++) {
Open->Group->array[i]->GroupHead = NULL;
}
if(--Open->Group->refcount == 0) {
ExFreePool(Open->Group);
}
NdisAcquireSpinLock(&Open->GroupLock);
if (Open->Group) {
for (unsigned int i=0; i < Open->Group->length; i++) {
Open->Group->array[i]->GroupHead = NULL;
}
if(--Open->Group->refcount == 0) {
ExFreePool(Open->Group);
}
}
NdisReleaseSpinLock(&Open->GroupLock);
NdisReleaseSpinLock(&Open->GroupLock);

NdisReleaseSpinLock(&g_OpenArrayLock);

Expand All @@ -1145,10 +1149,10 @@ NPF_RemoveFromGroupOpenArray(
POPEN_INSTANCE Open
)
{
POPEN_INSTANCE GroupHead = NULL;
OPEN_ARRAY *tempArray = NULL;
unsigned int newLen = 0;
unsigned int curr = 0;
POPEN_INSTANCE GroupHead = NULL;
OPEN_ARRAY *tempArray = NULL;
unsigned int newLen = 0;
unsigned int curr = 0;

TRACE_ENTER();

Expand All @@ -1158,55 +1162,55 @@ NPF_RemoveFromGroupOpenArray(
TRACE_EXIT();
return;
}
GroupHead = Open->GroupHead;

NdisAcquireSpinLock(&GroupHead->GroupLock);

if (GroupHead->Group) {
newLen = GroupHead->Group->length - 1;
}

/* Make a new OPEN_ARRAY with room for all the current Opens minus this one */
/* Because the OPEN_ARRAY contains space for one Open pointer already, this
* space is one too large, but that's ok because it means we don't write off
* the end when copying over in the unexpected case where Open is not
* actually in this group. */
tempArray = ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_ARRAY) + newLen * sizeof(OPEN_INSTANCE *), 'PAOG');
if (tempArray == NULL) {
// no memory
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Failed to allocate memory pool");
NdisReleaseSpinLock(&GroupHead->GroupLock);
TRACE_EXIT();
return;
}

/* Copy over the old array */
if (GroupHead->Group) {
for (unsigned int i=0; i < GroupHead->Group->length; i++) {
if (GroupHead->Group->array[i] == Open) {
/* pass */;
}
else {
tempArray->array[curr++] = GroupHead->Group->array[i];
}
}
/* If we're the last ones using the old copy, free it */
if (--GroupHead->Group->refcount == 0) {
ExFreePool(GroupHead->Group);
GroupHead = Open->GroupHead;

NdisAcquireSpinLock(&GroupHead->GroupLock);

if (GroupHead->Group) {
newLen = GroupHead->Group->length - 1;
}

/* Make a new OPEN_ARRAY with room for all the current Opens minus this one */
/* Because the OPEN_ARRAY contains space for one Open pointer already, this
* space is one too large, but that's ok because it means we don't write off
* the end when copying over in the unexpected case where Open is not
* actually in this group. */
tempArray = ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_ARRAY) + newLen * sizeof(OPEN_INSTANCE *), 'PAOG');
if (tempArray == NULL) {
// no memory
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Failed to allocate memory pool");
NdisReleaseSpinLock(&GroupHead->GroupLock);
TRACE_EXIT();
return;
}

/* Copy over the old array */
if (GroupHead->Group) {
for (unsigned int i=0; i < GroupHead->Group->length; i++) {
if (GroupHead->Group->array[i] == Open) {
/* pass */;
}
else {
tempArray->array[curr++] = GroupHead->Group->array[i];
}
}
/* If we're the last ones using the old copy, free it */
if (--GroupHead->Group->refcount == 0) {
ExFreePool(GroupHead->Group);
}
}

/* Initialize length and refcount and swap in */
tempArray->length = newLen;
tempArray->refcount = 1;
GroupHead->Group = tempArray;

NdisReleaseSpinLock(&GroupHead->GroupLock);

if (curr > newLen) {
IF_LOUD(DbgPrint("NPF_RemoveFromGroupOpenArray: error, the open isn't in the group open list.\n");)
}

/* Initialize length and refcount and swap in */
tempArray->length = newLen;
tempArray->refcount = 1;
GroupHead->Group = tempArray;

NdisReleaseSpinLock(&GroupHead->GroupLock);

if (curr > newLen) {
IF_LOUD(DbgPrint("NPF_RemoveFromGroupOpenArray: error, the open isn't in the group open list.\n");)
}

TRACE_EXIT();
}

Expand Down Expand Up @@ -1916,39 +1920,39 @@ NOTE: Called at PASSIVE_LEVEL and the filter is in paused state
{
POPEN_INSTANCE Open = (POPEN_INSTANCE) FilterModuleContext;
POPEN_INSTANCE GroupOpen;
OPEN_ARRAY *TempArray = NULL;
OPEN_ARRAY *TempArray = NULL;
BOOLEAN bFalse = FALSE;

TRACE_ENTER();

/* Lock the group */
NdisAcquireSpinLock(&Open->GroupLock);
/* Grab a local pointer to the copy we're using */
TempArray = Open->Group;
/* Double-check there is even a group here */
if (TempArray) {
/* Increment the refcount on this so nobody frees it while we're iterating */
TempArray->refcount++;
/* Release the lock, allow others to replace the list if necessary */
NdisReleaseSpinLock(&Open->GroupLock);

for (unsigned int i=0; i < TempArray->length; i++) {
GroupOpen = TempArray->array[i];
NPF_CloseOpenInstance(GroupOpen);

if (GroupOpen->ReadEvent != NULL)
KeSetEvent(GroupOpen->ReadEvent, 0, FALSE);
}

/* Reacquire the lock to make sure nobody mucks with refcount after we check it */
NdisAcquireSpinLock(&Open->GroupLock);
/* Decrement the refcount and check if we were the last ones using this copy */
if (--TempArray->refcount == 0) {
ExFreePool(TempArray);
}
}
/* Release the spin lock no matter what. */
NdisReleaseSpinLock(&Open->GroupLock);
/* Lock the group */
NdisAcquireSpinLock(&Open->GroupLock);
/* Grab a local pointer to the copy we're using */
TempArray = Open->Group;
/* Double-check there is even a group here */
if (TempArray) {
/* Increment the refcount on this so nobody frees it while we're iterating */
TempArray->refcount++;
/* Release the lock, allow others to replace the list if necessary */
NdisReleaseSpinLock(&Open->GroupLock);

for (unsigned int i=0; i < TempArray->length; i++) {
GroupOpen = TempArray->array[i];
NPF_CloseOpenInstance(GroupOpen);

if (GroupOpen->ReadEvent != NULL)
KeSetEvent(GroupOpen->ReadEvent, 0, FALSE);
}

/* Reacquire the lock to make sure nobody mucks with refcount after we check it */
NdisAcquireSpinLock(&Open->GroupLock);
/* Decrement the refcount and check if we were the last ones using this copy */
if (--TempArray->refcount == 0) {
ExFreePool(TempArray);
}
}
/* Release the spin lock no matter what. */
NdisReleaseSpinLock(&Open->GroupLock);

NPF_CloseBinding(Open);

Expand Down

0 comments on commit 09bbc7a

Please sign in to comment.