- Prevent corruption of the search context list using a combination of references and broader spin lock usage
- Fixes bug 6506

svn path=/trunk/; revision=54167
This commit is contained in:
Cameron Gutman 2011-10-16 22:21:41 +00:00
parent a4ea03f3c4
commit 6e8abd6c56

View file

@ -35,11 +35,21 @@ PADDRESS_FILE AddrSearchFirst(
USHORT Protocol,
PAF_SEARCH SearchContext)
{
KIRQL OldIrql;
SearchContext->Address = Address;
SearchContext->Port = Port;
SearchContext->Next = AddressFileListHead.Flink;
SearchContext->Protocol = Protocol;
TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
SearchContext->Next = AddressFileListHead.Flink;
if (!IsListEmpty(&AddressFileListHead))
ReferenceObject(CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry));
TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
return AddrSearchNext(SearchContext);
}
@ -104,14 +114,20 @@ PADDRESS_FILE AddrSearchNext(
KIRQL OldIrql;
PADDRESS_FILE Current = NULL;
BOOLEAN Found = FALSE;
TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
if (IsListEmpty(SearchContext->Next))
if (SearchContext->Next == &AddressFileListHead)
{
TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
return NULL;
}
/* Remove the extra reference we added to keep this address file in memory */
DereferenceObject(CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry));
CurrentEntry = SearchContext->Next;
TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
while (CurrentEntry != &AddressFileListHead) {
Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_FILE, ListEntry);
@ -136,13 +152,22 @@ PADDRESS_FILE AddrSearchNext(
CurrentEntry = CurrentEntry->Flink;
}
if (Found)
{
SearchContext->Next = CurrentEntry->Flink;
if (SearchContext->Next != &AddressFileListHead)
{
/* Reference the next address file to prevent the link from disappearing behind our back */
ReferenceObject(CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry));
}
}
else
Current = NULL;
TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
if (Found) {
SearchContext->Next = CurrentEntry->Flink;
return Current;
} else
return NULL;
return Current;
}
VOID AddrFileFree(