diff --git a/NetworkPkg/HttpBootDxe/HttpBootDhcp4.h b/NetworkPkg/HttpBootDxe/HttpBootDhcp4.h index 27d949850a..0b2cafbf50 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDhcp4.h +++ b/NetworkPkg/HttpBootDxe/HttpBootDhcp4.h @@ -178,10 +178,12 @@ typedef struct { UINT32 Reserved; } HTTP_BOOT_VENDOR_OPTION; +#define HTTP_CACHED_DHCP4_PACKET_MAX_SIZE (OFFSET_OF (EFI_DHCP4_PACKET, Dhcp4) + HTTP_BOOT_DHCP4_PACKET_MAX_SIZE) + typedef union { EFI_DHCP4_PACKET Offer; EFI_DHCP4_PACKET Ack; - UINT8 Buffer[HTTP_BOOT_DHCP4_PACKET_MAX_SIZE]; + UINT8 Buffer[HTTP_CACHED_DHCP4_PACKET_MAX_SIZE]; } HTTP_BOOT_DHCP4_PACKET; typedef struct { diff --git a/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c b/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c index 847864203c..ca84f2ad9b 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c +++ b/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c @@ -427,6 +427,12 @@ HttpBootDhcp6CallBack ( case Dhcp6RcvdAdvertise: Status = EFI_NOT_READY; + if (Packet->Length > HTTP_BOOT_DHCP6_PACKET_MAX_SIZE) { + // + // Ignore the incoming packets which exceed the maximum length. + // + break; + } if (Private->OfferNum < HTTP_BOOT_OFFER_MAX_NUM) { // // Cache the dhcp offers to OfferBuffer[] for select later, and record diff --git a/NetworkPkg/HttpBootDxe/HttpBootDhcp6.h b/NetworkPkg/HttpBootDxe/HttpBootDhcp6.h index 14d6db0648..9f2989831e 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootDhcp6.h +++ b/NetworkPkg/HttpBootDxe/HttpBootDhcp6.h @@ -75,10 +75,12 @@ typedef union { HTTP_BOOT_DHCP6_OPTION_VENDOR_CLASS *VendorClass; } HTTP_BOOT_DHCP6_OPTION_ENTRY; +#define HTTP_CACHED_DHCP6_PACKET_MAX_SIZE (OFFSET_OF (EFI_DHCP6_PACKET, Dhcp6) + HTTP_BOOT_DHCP6_PACKET_MAX_SIZE) + typedef union { EFI_DHCP6_PACKET Offer; EFI_DHCP6_PACKET Ack; - UINT8 Buffer[HTTP_BOOT_DHCP6_PACKET_MAX_SIZE]; + UINT8 Buffer[HTTP_CACHED_DHCP6_PACKET_MAX_SIZE]; } HTTP_BOOT_DHCP6_PACKET; typedef struct { diff --git a/NetworkPkg/HttpBootDxe/HttpBootImpl.c b/NetworkPkg/HttpBootDxe/HttpBootImpl.c index babd3e6194..cf6de80a17 100644 --- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c +++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c @@ -126,11 +126,11 @@ HttpBootStart ( ZeroMem (Private->OfferBuffer, sizeof (Private->OfferBuffer)); if (!Private->UsingIpv6) { for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) { - Private->OfferBuffer[Index].Dhcp4.Packet.Offer.Size = HTTP_BOOT_DHCP4_PACKET_MAX_SIZE; + Private->OfferBuffer[Index].Dhcp4.Packet.Offer.Size = HTTP_CACHED_DHCP4_PACKET_MAX_SIZE; } } else { for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) { - Private->OfferBuffer[Index].Dhcp6.Packet.Offer.Size = HTTP_BOOT_DHCP6_PACKET_MAX_SIZE; + Private->OfferBuffer[Index].Dhcp6.Packet.Offer.Size = HTTP_CACHED_DHCP6_PACKET_MAX_SIZE; } } diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c index 6566afd6af..44b0714393 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c @@ -256,7 +256,7 @@ PxeBcBuildDhcp4Options ( OptList[Index]->OpCode = DHCP4_TAG_MAXMSG; OptList[Index]->Length = (UINT8) sizeof (PXEBC_DHCP4_OPTION_MAX_MESG_SIZE); OptEnt.MaxMesgSize = (PXEBC_DHCP4_OPTION_MAX_MESG_SIZE *) OptList[Index]->Data; - Value = NTOHS (PXEBC_DHCP4_PACKET_MAX_SIZE - 8); + Value = NTOHS (PXEBC_DHCP4_PACKET_MAX_SIZE); CopyMem (&OptEnt.MaxMesgSize->Size, &Value, sizeof (UINT16)); Index++; OptList[Index] = GET_NEXT_DHCP_OPTION (OptList[Index - 1]); @@ -1183,7 +1183,7 @@ PxeBcDhcp4CallBack ( DHCP4_TAG_MAXMSG ); if (MaxMsgSize != NULL) { - Value = HTONS (PXEBC_DHCP4_PACKET_MAX_SIZE - 8); + Value = HTONS (PXEBC_DHCP4_PACKET_MAX_SIZE); CopyMem (MaxMsgSize->Data, &Value, sizeof (Value)); } @@ -1209,6 +1209,14 @@ PxeBcDhcp4CallBack ( switch (Dhcp4Event) { case Dhcp4SendDiscover: + if (Packet->Length > PXEBC_DHCP4_PACKET_MAX_SIZE) { + // + // If the to be sent packet exceeds the maximum length, abort the DHCP process. + // + Status = EFI_ABORTED; + break; + } + // // Cache the DHCPv4 discover packet to mode data directly. // It need to check SendGuid as well as Dhcp4SendRequest. @@ -1216,6 +1224,14 @@ PxeBcDhcp4CallBack ( CopyMem (&Mode->DhcpDiscover.Dhcpv4, &Packet->Dhcp4, Packet->Length); case Dhcp4SendRequest: + if (Packet->Length > PXEBC_DHCP4_PACKET_MAX_SIZE) { + // + // If the to be sent packet exceeds the maximum length, abort the DHCP process. + // + Status = EFI_ABORTED; + break; + } + if (Mode->SendGUID) { // // Send the system Guid instead of the MAC address as the hardware address if required. @@ -1232,6 +1248,12 @@ PxeBcDhcp4CallBack ( case Dhcp4RcvdOffer: Status = EFI_NOT_READY; + if (Packet->Length > PXEBC_DHCP4_PACKET_MAX_SIZE) { + // + // Ignore the incoming packets which exceed the maximum length. + // + break; + } if (Private->OfferNum < PXEBC_OFFER_MAX_NUM) { // // Cache the DHCPv4 offers to OfferBuffer[] for select later, and record @@ -1256,6 +1278,14 @@ PxeBcDhcp4CallBack ( break; case Dhcp4RcvdAck: + if (Packet->Length > PXEBC_DHCP4_PACKET_MAX_SIZE) { + // + // Abort the DHCP if the ACK packet exceeds the maximum length. + // + Status = EFI_ABORTED; + break; + } + // // Cache the DHCPv4 ack to Private->Dhcp4Ack, but it's not the final ack in mode data // without verification. diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h index 3aabaed088..27794c911a 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h @@ -18,7 +18,7 @@ #define PXEBC_DHCP4_OPTION_MAX_NUM 16 #define PXEBC_DHCP4_OPTION_MAX_SIZE 312 -#define PXEBC_DHCP4_PACKET_MAX_SIZE 1472 +#define PXEBC_DHCP4_PACKET_MAX_SIZE (sizeof (EFI_PXE_BASE_CODE_PACKET)) #define PXEBC_DHCP4_S_PORT 67 #define PXEBC_DHCP4_C_PORT 68 #define PXEBC_BS_DOWNLOAD_PORT 69 @@ -263,10 +263,12 @@ typedef struct { UINT8 CredTypeLen; } PXEBC_VENDOR_OPTION; +#define PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE (OFFSET_OF (EFI_DHCP4_PACKET, Dhcp4) + PXEBC_DHCP4_PACKET_MAX_SIZE) + typedef union { EFI_DHCP4_PACKET Offer; EFI_DHCP4_PACKET Ack; - UINT8 Buffer[PXEBC_DHCP4_PACKET_MAX_SIZE]; + UINT8 Buffer[PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE]; } PXEBC_DHCP4_PACKET; typedef struct { diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c index eba8e1d27b..6a08e9a2de 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c @@ -1919,6 +1919,14 @@ PxeBcDhcp6CallBack ( switch (Dhcp6Event) { case Dhcp6SendSolicit: + if (Packet->Length > PXEBC_DHCP6_PACKET_MAX_SIZE) { + // + // If the to be sent packet exceeds the maximum length, abort the DHCP process. + // + Status = EFI_ABORTED; + break; + } + // // Record the first Solicate msg time // @@ -1934,6 +1942,12 @@ PxeBcDhcp6CallBack ( case Dhcp6RcvdAdvertise: Status = EFI_NOT_READY; + if (Packet->Length > PXEBC_DHCP6_PACKET_MAX_SIZE) { + // + // Ignore the incoming packets which exceed the maximum length. + // + break; + } if (Private->OfferNum < PXEBC_OFFER_MAX_NUM) { // // Cache the dhcp offers to OfferBuffer[] for select later, and record @@ -1944,6 +1958,14 @@ PxeBcDhcp6CallBack ( break; case Dhcp6SendRequest: + if (Packet->Length > PXEBC_DHCP6_PACKET_MAX_SIZE) { + // + // If the to be sent packet exceeds the maximum length, abort the DHCP process. + // + Status = EFI_ABORTED; + break; + } + // // Store the request packet as seed packet for discover. // @@ -1975,6 +1997,13 @@ PxeBcDhcp6CallBack ( break; case Dhcp6RcvdReply: + if (Packet->Length > PXEBC_DHCP6_PACKET_MAX_SIZE) { + // + // Abort the DHCP if the Peply packet exceeds the maximum length. + // + Status = EFI_ABORTED; + break; + } // // Cache the dhcp ack to Private->Dhcp6Ack, but it's not the final ack in mode data // without verification. diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h index 9493b164cb..39efcfaa77 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h @@ -18,7 +18,7 @@ #define PXEBC_DHCP6_OPTION_MAX_NUM 16 #define PXEBC_DHCP6_OPTION_MAX_SIZE 312 -#define PXEBC_DHCP6_PACKET_MAX_SIZE 1472 +#define PXEBC_DHCP6_PACKET_MAX_SIZE (sizeof (EFI_PXE_BASE_CODE_PACKET)) #define PXEBC_IP6_POLICY_MAX 0xff #define PXEBC_IP6_ROUTE_TABLE_TIMEOUT 10 @@ -101,10 +101,12 @@ typedef struct { UINT8 Precedence; } PXEBC_DHCP6_OPTION_NODE; +#define PXEBC_CACHED_DHCP6_PACKET_MAX_SIZE (OFFSET_OF (EFI_DHCP6_PACKET, Dhcp6) + PXEBC_DHCP6_PACKET_MAX_SIZE) + typedef union { EFI_DHCP6_PACKET Offer; EFI_DHCP6_PACKET Ack; - UINT8 Buffer[PXEBC_DHCP6_PACKET_MAX_SIZE]; + UINT8 Buffer[PXEBC_CACHED_DHCP6_PACKET_MAX_SIZE]; } PXEBC_DHCP6_PACKET; typedef struct { diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c index 0552174ac6..e24c573e32 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c @@ -102,12 +102,12 @@ EfiPxeBcStart ( // PXE over IPv6 starts here, initialize the fields and list header. // Private->Ip6Policy = PXEBC_IP6_POLICY_MAX; - Private->ProxyOffer.Dhcp6.Packet.Offer.Size = PXEBC_DHCP6_PACKET_MAX_SIZE; - Private->DhcpAck.Dhcp6.Packet.Ack.Size = PXEBC_DHCP6_PACKET_MAX_SIZE; - Private->PxeReply.Dhcp6.Packet.Ack.Size = PXEBC_DHCP6_PACKET_MAX_SIZE; + Private->ProxyOffer.Dhcp6.Packet.Offer.Size = PXEBC_CACHED_DHCP6_PACKET_MAX_SIZE; + Private->DhcpAck.Dhcp6.Packet.Ack.Size = PXEBC_CACHED_DHCP6_PACKET_MAX_SIZE; + Private->PxeReply.Dhcp6.Packet.Ack.Size = PXEBC_CACHED_DHCP6_PACKET_MAX_SIZE; for (Index = 0; Index < PXEBC_OFFER_MAX_NUM; Index++) { - Private->OfferBuffer[Index].Dhcp6.Packet.Offer.Size = PXEBC_DHCP6_PACKET_MAX_SIZE; + Private->OfferBuffer[Index].Dhcp6.Packet.Offer.Size = PXEBC_CACHED_DHCP6_PACKET_MAX_SIZE; } // @@ -154,12 +154,12 @@ EfiPxeBcStart ( // // PXE over IPv4 starts here, initialize the fields. // - Private->ProxyOffer.Dhcp4.Packet.Offer.Size = PXEBC_DHCP4_PACKET_MAX_SIZE; - Private->DhcpAck.Dhcp4.Packet.Ack.Size = PXEBC_DHCP4_PACKET_MAX_SIZE; - Private->PxeReply.Dhcp4.Packet.Ack.Size = PXEBC_DHCP4_PACKET_MAX_SIZE; + Private->ProxyOffer.Dhcp4.Packet.Offer.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE; + Private->DhcpAck.Dhcp4.Packet.Ack.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE; + Private->PxeReply.Dhcp4.Packet.Ack.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE; for (Index = 0; Index < PXEBC_OFFER_MAX_NUM; Index++) { - Private->OfferBuffer[Index].Dhcp4.Packet.Offer.Size = PXEBC_DHCP4_PACKET_MAX_SIZE; + Private->OfferBuffer[Index].Dhcp4.Packet.Offer.Size = PXEBC_CACHED_DHCP4_PACKET_MAX_SIZE; } PxeBcSeedDhcp4Packet (&Private->SeedPacket, Private->Udp4Read);