- 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
This commit is contained in:
Cameron Gutman 2014-08-17 04:03:29 +00:00
parent ef4815c35f
commit 87f8f559cc
3 changed files with 12 additions and 3 deletions

View 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;

View 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 */

View 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 */