[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 2/2] Validate buffer length in ParsePacket


  • To: Owen Smith <owen.smith@xxxxxxxxxx>, win-pv-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
  • Date: Fri, 3 Jul 2026 21:51:03 +0200
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID"
  • Delivery-date: Fri, 03 Jul 2026 19:51:12 +0000
  • Feedback-id: default:8631fc262581453bbf619ec5b2062170:Sweego
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

On 03/07/2026 14:22, Owen Smith wrote:
> 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>

Reviewed-by: Tu Dinh <ngoc-tu.dinh@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;
>   



--
Ngoc Tu Dinh | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.