From 6e8abd6c5644ae968669bc17d81be1c14ec02bcb Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 16 Oct 2011 22:21:41 +0000 Subject: [PATCH] [TCPIP] - 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 --- .../drivers/network/tcpip/tcpip/fileobjs.c | 43 +++++++++++++++---- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/reactos/drivers/network/tcpip/tcpip/fileobjs.c b/reactos/drivers/network/tcpip/tcpip/fileobjs.c index e47f700d42f..6c475eeb3c4 100644 --- a/reactos/drivers/network/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/network/tcpip/tcpip/fileobjs.c @@ -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(