[TCPIP]
authorCameron Gutman <aicommander@gmail.com>
Sun, 16 Oct 2011 22:21:41 +0000 (22:21 +0000)
committerCameron Gutman <aicommander@gmail.com>
Sun, 16 Oct 2011 22:21:41 +0000 (22:21 +0000)
- 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

reactos/drivers/network/tcpip/tcpip/fileobjs.c

index e47f700..6c475ee 100644 (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,13 +114,19 @@ 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;
+    }
 
-    CurrentEntry = SearchContext->Next;
+    /* Remove the extra reference we added to keep this address file in memory */
+    DereferenceObject(CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry));
 
-    TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
+    CurrentEntry = SearchContext->Next;
 
     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(