[TCPIP]
authorCameron Gutman <aicommander@gmail.com>
Sun, 17 Aug 2014 04:03:29 +0000 (04:03 +0000)
committerCameron Gutman <aicommander@gmail.com>
Sun, 17 Aug 2014 04:03:29 +0000 (04:03 +0000)
- Reference the address file while delivering data to avoid a use after free when an address file is closed during datagram delivery

svn path=/trunk/; revision=63899

reactos/drivers/network/tcpip/tcpip/fileobjs.c
reactos/lib/drivers/ip/transport/rawip/rawip.c
reactos/lib/drivers/ip/transport/udp/udp.c

index bd696b7..313e9d1 100644 (file)
@@ -222,7 +222,7 @@ PADDRESS_FILE AddrFindShared(
  * ARGUMENTS:
  *     SearchContext = Pointer to search context
  * RETURNS:
- *     Pointer to address file, NULL if none was found
+ *     Pointer to referenced address file, NULL if none was found
  */
 PADDRESS_FILE AddrSearchNext(
     PAF_SEARCH SearchContext)
@@ -232,6 +232,7 @@ PADDRESS_FILE AddrSearchNext(
     KIRQL OldIrql;
     PADDRESS_FILE Current = NULL;
     BOOLEAN Found = FALSE;
+    PADDRESS_FILE StartingAddrFile;
     
     TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
 
@@ -241,8 +242,8 @@ PADDRESS_FILE AddrSearchNext(
         return NULL;
     }
 
-    /* Remove the extra reference we added to keep this address file in memory */
-    DereferenceObject(CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry));
+    /* Save this pointer so we can dereference it later */
+    StartingAddrFile = CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry);
 
     CurrentEntry = SearchContext->Next;
 
@@ -279,10 +280,16 @@ PADDRESS_FILE AddrSearchNext(
             /* Reference the next address file to prevent the link from disappearing behind our back */
             ReferenceObject(CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry));
         }
+
+        /* Reference the returned address file before dereferencing the starting
+         * address file because it may be that Current == StartingAddrFile */
+        ReferenceObject(Current);
     }
     else
         Current = NULL;
 
+    DereferenceObject(StartingAddrFile);
+
     TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
 
     return Current;
index 467fe39..180f545 100644 (file)
@@ -321,6 +321,7 @@ VOID RawIpReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
                     0,
                     IPPacket,
                     DataSize);
+      DereferenceObject(AddrFile);
     } while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL);
   } else {
     /* There are no open address files that will take this datagram */
index 1629aad..2f7dae9 100644 (file)
@@ -320,6 +320,7 @@ VOID UDPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
                    UDPHeader->DestPort,
                     IPPacket,
                     DataSize);
+      DereferenceObject(AddrFile);
     } while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL);
   } else {
     /* There are no open address files that will take this datagram */