- 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: * ARGUMENTS:
* SearchContext = Pointer to search context * SearchContext = Pointer to search context
* RETURNS: * RETURNS:
* Pointer to address file, NULL if none was found * Pointer to referenced address file, NULL if none was found
*/ */
PADDRESS_FILE AddrSearchNext( PADDRESS_FILE AddrSearchNext(
PAF_SEARCH SearchContext) PAF_SEARCH SearchContext)
@ -232,6 +232,7 @@ PADDRESS_FILE AddrSearchNext(
KIRQL OldIrql; KIRQL OldIrql;
PADDRESS_FILE Current = NULL; PADDRESS_FILE Current = NULL;
BOOLEAN Found = FALSE; BOOLEAN Found = FALSE;
PADDRESS_FILE StartingAddrFile;
TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql); TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
@ -241,8 +242,8 @@ PADDRESS_FILE AddrSearchNext(
return NULL; return NULL;
} }
/* Remove the extra reference we added to keep this address file in memory */ /* Save this pointer so we can dereference it later */
DereferenceObject(CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry)); StartingAddrFile = CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry);
CurrentEntry = SearchContext->Next; CurrentEntry = SearchContext->Next;
@ -279,10 +280,16 @@ PADDRESS_FILE AddrSearchNext(
/* Reference the next address file to prevent the link from disappearing behind our back */ /* Reference the next address file to prevent the link from disappearing behind our back */
ReferenceObject(CONTAINING_RECORD(SearchContext->Next, ADDRESS_FILE, ListEntry)); 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 else
Current = NULL; Current = NULL;
DereferenceObject(StartingAddrFile);
TcpipReleaseSpinLock(&AddressFileListLock, OldIrql); TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
return Current; return Current;

View file

@ -321,6 +321,7 @@ VOID RawIpReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
0, 0,
IPPacket, IPPacket,
DataSize); DataSize);
DereferenceObject(AddrFile);
} while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL); } while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL);
} else { } else {
/* There are no open address files that will take this datagram */ /* 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, UDPHeader->DestPort,
IPPacket, IPPacket,
DataSize); DataSize);
DereferenceObject(AddrFile);
} while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL); } while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL);
} else { } else {
/* There are no open address files that will take this datagram */ /* There are no open address files that will take this datagram */