From: Paul Durrant Date: Wed, 8 Feb 2017 10:47:06 +0000 (+0000) Subject: Fix low resources packet leak X-Git-Tag: 9.0.0-rc1~17 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=92885c70c810231ad95a1c7e06da09fd1415421a;p=pvdrivers%2Fwin%2Fxennet.git Fix low resources packet leak When the low resources limit is hit then the NDIS_RECEIVE_FLAGS_RESOURCES is passed to NdisMIndicateReceiveNetBufferLists(), which means that the calling code can assume the NET_BUFFER_LIST is immediately released. The code therefore attempts to immediately release the chain of NET_BUFFER_LIST, but because __IndicateReceiveNetBufferLists() segmented the chain, only the first one is actually released. This leads to a resource leak which also prevents XENVIF from shutting down correctly (waiting for the leaked packets to be returned). This patch fixes the issue by handling the release of individual NET_BUFFER_LISTs directly in __IndicateReceiveNetBufferLists(), if the NDIS_RECEIVE_FLAGS_RESOURCES is set. Reported-by: Martin Cerveny Signed-off-by: Paul Durrant Tested-by: Martin Cerveny --- diff --git a/src/xennet/receiver.c b/src/xennet/receiver.c index 1e6775e..2f7ea25 100644 --- a/src/xennet/receiver.c +++ b/src/xennet/receiver.c @@ -328,15 +328,20 @@ fail1: } static FORCEINLINE VOID __IndicateReceiveNetBufferLists( - IN NDIS_HANDLE MiniportAdapterHandle, + IN PXENNET_RECEIVER Receiver, IN PNET_BUFFER_LIST NetBufferLists, IN NDIS_PORT_NUMBER PortNumber, IN ULONG NumberOfNetBufferLists, IN ULONG ReceiveFlags ) { + PXENNET_ADAPTER Adapter = Receiver->Adapter; + NDIS_HANDLE MiniportAdapterHandle = AdapterGetHandle(Adapter); + PXENVIF_VIF_INTERFACE VifInterface; ULONG Count; + VifInterface = AdapterGetVifInterface(Receiver->Adapter); + Count = 0; while (NetBufferLists != NULL) { PNET_BUFFER_LIST Next; @@ -350,6 +355,20 @@ static FORCEINLINE VOID __IndicateReceiveNetBufferLists( 1, ReceiveFlags); + if (ReceiveFlags & NDIS_RECEIVE_FLAGS_RESOURCES) { + PVOID Cookie; + + Cookie = __ReceiverReleaseNetBufferList(Receiver, + NetBufferLists, + FALSE); + + XENVIF_VIF(ReceiverReturnPacket, + VifInterface, + Cookie); + + (VOID) InterlockedIncrement(&Receiver->Returned); + } + Count++; NetBufferLists = Next; } @@ -396,14 +415,11 @@ __ReceiverPushPackets( if (Indicated - Returned > IN_NDIS_MAX) Flags |= NDIS_RECEIVE_FLAGS_RESOURCES; - __IndicateReceiveNetBufferLists(AdapterGetHandle(Receiver->Adapter), + __IndicateReceiveNetBufferLists(Receiver, NetBufferList, NDIS_DEFAULT_PORT_NUMBER, Count, Flags); - - if (Flags & NDIS_RECEIVE_FLAGS_RESOURCES) - (VOID) __ReceiverReturnNetBufferLists(Receiver, NetBufferList, FALSE); } NDIS_STATUS