|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 2/2] Validate buffer length in ParsePacket
By passing the destination buffer length to ParsePacket, its possible to
detect a potential buffer overrun. This is likely only an issue when
TransmitterQueuePacket attempts to parse an IPv6 packet with sufficient
option headers to exceed XENVIF_TRANSMITTER_MAXIMUM_HEADER_LENGTH (512 bytes)
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
src/xenvif/parse.c | 36 ++++++++++++++++++++++++++++++++++++
src/xenvif/parse.h | 1 +
src/xenvif/receiver.c | 7 ++++++-
src/xenvif/transmitter.c | 7 ++++++-
4 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/src/xenvif/parse.c b/src/xenvif/parse.c
index 2e5000d..4f4f773 100644
--- a/src/xenvif/parse.c
+++ b/src/xenvif/parse.c
@@ -49,11 +49,17 @@ __ParsePullup(
IN XENVIF_PARSE_PULLUP Pullup,
IN PVOID Argument,
IN PUCHAR StartVa,
+ IN ULONG StartLen,
IN ULONG Offset,
IN PXENVIF_PACKET_PAYLOAD Payload,
IN ULONG Length
)
{
+ ASSERT3U(StartLen, >, Offset);
+
+ if (StartLen - Offset < Length)
+ return FALSE;
+
return Pullup(Argument,
StartVa + Offset,
Payload,
@@ -63,6 +69,7 @@ __ParsePullup(
static FORCEINLINE NTSTATUS
__ParseTcpHeader(
IN PUCHAR StartVa,
+ IN ULONG StartLen,
IN ULONG Offset,
IN XENVIF_PARSE_PULLUP Pullup,
IN PVOID Argument,
@@ -77,6 +84,7 @@ __ParseTcpHeader(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
sizeof (TCP_HEADER)))
@@ -101,6 +109,7 @@ __ParseTcpHeader(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
Extra))
@@ -130,6 +139,7 @@ fail1:
static FORCEINLINE NTSTATUS
__ParseUdpHeader(
IN PUCHAR StartVa,
+ IN ULONG StartLen,
IN ULONG Offset,
IN XENVIF_PARSE_PULLUP Pullup,
IN PVOID Argument,
@@ -142,6 +152,7 @@ __ParseUdpHeader(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
sizeof (UDP_HEADER)))
@@ -164,6 +175,7 @@ fail1:
static FORCEINLINE NTSTATUS
__ParseIpVersion4Header(
IN PUCHAR StartVa,
+ IN ULONG StartLen,
IN ULONG Offset,
IN XENVIF_PARSE_PULLUP Pullup,
IN PVOID Argument,
@@ -181,6 +193,7 @@ __ParseIpVersion4Header(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
sizeof (IPV4_HEADER)))
@@ -211,6 +224,7 @@ __ParseIpVersion4Header(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
Extra))
@@ -233,6 +247,7 @@ __ParseIpVersion4Header(
switch (Header->Protocol) {
case IPPROTO_TCP:
status = __ParseTcpHeader(StartVa,
+ StartLen,
Offset,
Pullup,
Argument,
@@ -242,6 +257,7 @@ __ParseIpVersion4Header(
case IPPROTO_UDP:
status = __ParseUdpHeader(StartVa,
+ StartLen,
Offset,
Pullup,
Argument,
@@ -274,6 +290,7 @@ fail1:
static FORCEINLINE NTSTATUS
__ParseIpVersion6Header(
IN PUCHAR StartVa,
+ IN ULONG StartLen,
IN ULONG Offset,
IN XENVIF_PARSE_PULLUP Pullup,
IN PVOID Argument,
@@ -293,6 +310,7 @@ __ParseIpVersion6Header(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
sizeof (IPV6_HEADER)))
@@ -325,6 +343,7 @@ __ParseIpVersion6Header(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
sizeof (IPV6_FRAGMENT_HEADER)))
@@ -346,6 +365,7 @@ __ParseIpVersion6Header(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
sizeof (IP_AUTHENTICATION_HEADER)))
@@ -360,6 +380,7 @@ __ParseIpVersion6Header(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
Extra))
@@ -379,6 +400,7 @@ __ParseIpVersion6Header(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
sizeof (IPV6_OPTION_HEADER)))
@@ -393,6 +415,7 @@ __ParseIpVersion6Header(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
Extra))
@@ -427,6 +450,7 @@ __ParseIpVersion6Header(
switch (NextHeader) {
case IPPROTO_TCP:
status = __ParseTcpHeader(StartVa,
+ StartLen,
Offset,
Pullup,
Argument,
@@ -436,6 +460,7 @@ __ParseIpVersion6Header(
case IPPROTO_UDP:
status = __ParseUdpHeader(StartVa,
+ StartLen,
Offset,
Pullup,
Argument,
@@ -469,6 +494,7 @@ fail1:
static FORCEINLINE NTSTATUS
__ParseLLCSnapHeader(
IN PUCHAR StartVa,
+ IN ULONG StartLen,
IN ULONG Offset,
IN XENVIF_PARSE_PULLUP Pullup,
IN PVOID Argument,
@@ -483,6 +509,7 @@ __ParseLLCSnapHeader(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
sizeof (LLC_U_HEADER)))
@@ -501,6 +528,7 @@ __ParseLLCSnapHeader(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
Extra))
@@ -525,6 +553,7 @@ fail1:
static FORCEINLINE NTSTATUS
__ParseEthernetHeader(
IN PUCHAR StartVa,
+ IN ULONG StartLen,
IN ULONG Offset,
IN XENVIF_PARSE_PULLUP Pullup,
IN PVOID Argument,
@@ -542,6 +571,7 @@ __ParseEthernetHeader(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
sizeof (ETHERNET_UNTAGGED_HEADER)))
@@ -562,6 +592,7 @@ __ParseEthernetHeader(
if (!__ParsePullup(Pullup,
Argument,
StartVa,
+ StartLen,
Offset,
Payload,
Extra))
@@ -580,6 +611,7 @@ __ParseEthernetHeader(
if (IsLLC) {
status = __ParseLLCSnapHeader(StartVa,
+ StartLen,
Offset,
Pullup,
Argument,
@@ -589,6 +621,7 @@ __ParseEthernetHeader(
switch (TypeOrLength) {
case ETHERTYPE_IPV4:
status = __ParseIpVersion4Header(StartVa,
+ StartLen,
Offset,
Pullup,
Argument,
@@ -598,6 +631,7 @@ __ParseEthernetHeader(
case ETHERTYPE_IPV6:
status = __ParseIpVersion6Header(StartVa,
+ StartLen,
Offset,
Pullup,
Argument,
@@ -623,6 +657,7 @@ fail1:
NTSTATUS
ParsePacket(
IN PUCHAR StartVa,
+ IN ULONG StartLen,
IN XENVIF_PARSE_PULLUP Pullup,
IN PVOID Argument,
IN OUT PXENVIF_PACKET_PAYLOAD Payload,
@@ -632,6 +667,7 @@ ParsePacket(
ASSERT(IsZeroMemory(Info, sizeof (XENVIF_PACKET_INFO)));
return __ParseEthernetHeader(StartVa,
+ StartLen,
0,
Pullup,
Argument,
diff --git a/src/xenvif/parse.h b/src/xenvif/parse.h
index d00d962..678991a 100644
--- a/src/xenvif/parse.h
+++ b/src/xenvif/parse.h
@@ -52,6 +52,7 @@ typedef BOOLEAN
extern NTSTATUS
ParsePacket(
IN PUCHAR StartVa,
+ IN ULONG StartLen,
IN XENVIF_PARSE_PULLUP Pullup,
IN PVOID Argument,
IN OUT PXENVIF_PACKET_PAYLOAD Payload,
diff --git a/src/xenvif/receiver.c b/src/xenvif/receiver.c
index 0ed46e6..14e8d0b 100644
--- a/src/xenvif/receiver.c
+++ b/src/xenvif/receiver.c
@@ -1268,7 +1268,12 @@ ReceiverRingProcessPacket(
Info = &Packet->Info;
- status = ParsePacket(BaseVa, ReceiverRingPullup, Ring, &Payload, Info);
+ status = ParsePacket(BaseVa,
+ PAGE_SIZE - Packet->Offset,
+ ReceiverRingPullup,
+ Ring,
+ &Payload,
+ Info);
if (!NT_SUCCESS(status)) {
FrontendIncrementStatistic(Frontend,
XENVIF_RECEIVER_FRONTEND_ERRORS,
diff --git a/src/xenvif/transmitter.c b/src/xenvif/transmitter.c
index 41d0f3c..b78a090 100644
--- a/src/xenvif/transmitter.c
+++ b/src/xenvif/transmitter.c
@@ -5209,7 +5209,12 @@ TransmitterQueuePacket(
Info = &Packet->Info;
- (VOID) ParsePacket(BaseVa, TransmitterPullup, Transmitter, Payload, Info);
+ (VOID) ParsePacket(BaseVa,
+ XENVIF_TRANSMITTER_MAXIMUM_HEADER_LENGTH,
+ TransmitterPullup,
+ Transmitter,
+ Payload,
+ Info);
Algorithm = Hash->Algorithm;
--
2.51.2.windows.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |