driver: do not assume aligned addresses when allocating MDLs

IoAllocateMdl allocates a different size structure depending on the
bottom in-page bits of the address. By passing null, it assumes that the
address is aligned within the page, which it might not be. Fix this by
passing the eventual virtual address to the allocation function so that
the right amount is always allocated.

Reported-by: Oleksandr Muzychuk <oleksandr.muzychuk@apriorit.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2021-05-10 19:02:49 +02:00
parent f19945b3c6
commit 6cf9ac71c3

View File

@ -517,13 +517,15 @@ TunProcessReceiveData(_Inout_ TUN_CTX *Ctx)
break;
RingHead = TUN_RING_WRAP(RingHead + AlignedPacketSize, RingCapacity);
MDL *Mdl = IoAllocateMdl(NULL, PacketSize, FALSE, FALSE, NULL);
VOID *PacketAddr =
(UCHAR *)MmGetMdlVirtualAddress(Ctx->Device.Receive.Mdl) + (ULONG)(Packet->Data - (UCHAR *)Ring);
MDL *Mdl = IoAllocateMdl(PacketAddr, PacketSize, FALSE, FALSE, NULL);
if (!Mdl)
goto skipNbl;
IoBuildPartialMdl(
Ctx->Device.Receive.Mdl,
Mdl,
(UCHAR *)MmGetMdlVirtualAddress(Ctx->Device.Receive.Mdl) + (ULONG)(Packet->Data - (UCHAR *)Ring),
PacketAddr,
PacketSize);
NET_BUFFER_LIST *Nbl = NdisAllocateNetBufferAndNetBufferList(Ctx->NblPool, 0, 0, Mdl, 0, PacketSize);
if (!Nbl)