aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--driver/wintun.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/driver/wintun.c b/driver/wintun.c
index a762dcb..b833663 100644
--- a/driver/wintun.c
+++ b/driver/wintun.c
@@ -412,6 +412,16 @@ TunReturnNetBufferLists(NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST Net
KeSetEvent(&Ctx->Device.Receive.ActiveNbls.Empty, IO_NO_INCREMENT, FALSE);
KeReleaseInStackQueuedSpinLock(&LockHandle);
WriteULongRelease(&Ring->Head, TunNblGetOffset(CompletedNbl));
+ const MDL *TargetMdl = Ctx->Device.Receive.Mdl;
+ for (MDL *Mdl = NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB(CompletedNbl)); Mdl; Mdl = Mdl->Next)
+ {
+ if (MmGetMdlVirtualAddress(Mdl) < MmGetMdlVirtualAddress(TargetMdl) ||
+ (UCHAR *)MmGetMdlVirtualAddress(Mdl) + MmGetMdlByteCount(Mdl) >
+ (UCHAR *)MmGetMdlVirtualAddress(TargetMdl) + MmGetMdlByteCount(TargetMdl))
+ continue;
+ IoFreeMdl(Mdl);
+ break;
+ }
NdisFreeNetBufferList(CompletedNbl);
}
}
@@ -507,20 +517,17 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx)
break;
RingHead = TUN_RING_WRAP(RingHead + AlignedPacketSize, RingCapacity);
- MDL *Mdl;
- NET_BUFFER_LIST *Nbl = NdisAllocateNetBufferAndNetBufferList(Ctx->NblPool, sizeof(*Mdl), 0, NULL, 0, 0);
- if (!Nbl)
+ MDL *Mdl = IoAllocateMdl(NULL, PacketSize, FALSE, FALSE, NULL);
+ if (!Mdl)
goto skipNbl;
- Mdl = (MDL *)NET_BUFFER_LIST_CONTEXT_DATA_START(Nbl);
IoBuildPartialMdl(
Ctx->Device.Receive.Mdl,
Mdl,
(UCHAR *)MmGetMdlVirtualAddress(Ctx->Device.Receive.Mdl) + (ULONG)(Packet->Data - (UCHAR *)Ring),
PacketSize);
- NET_BUFFER *Nb = NET_BUFFER_LIST_FIRST_NB(Nbl);
- NET_BUFFER_FIRST_MDL(Nb) = NET_BUFFER_CURRENT_MDL(Nb) = Mdl;
- NET_BUFFER_DATA_LENGTH(Nb) = PacketSize;
- NET_BUFFER_DATA_OFFSET(Nb) = NET_BUFFER_CURRENT_MDL_OFFSET(Nb) = 0;
+ NET_BUFFER_LIST *Nbl = NdisAllocateNetBufferAndNetBufferList(Ctx->NblPool, 0, 0, Mdl, 0, PacketSize);
+ if (!Nbl)
+ goto cleanupMdl;
Nbl->SourceHandle = Ctx->MiniportAdapterHandle;
NdisSetNblFlag(Nbl, NblFlags);
NET_BUFFER_LIST_INFO(Nbl, NetBufferListFrameType) = (PVOID)NblProto;
@@ -556,6 +563,8 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx)
cleanupNbl:
ExReleaseSpinLockShared(&Ctx->TransitionLock, Irql);
NdisFreeNetBufferList(Nbl);
+ cleanupMdl:
+ IoFreeMdl(Mdl);
skipNbl:
InterlockedIncrementNoFence64((LONG64 *)&Ctx->Statistics.ifInDiscards);
KeWaitForSingleObject(&Ctx->Device.Receive.ActiveNbls.Empty, Executive, KernelMode, FALSE, NULL);