summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFu Siyuan <siyuan.fu@intel.com>2016-11-16 13:37:15 +0800
committerFu Siyuan <siyuan.fu@intel.com>2016-11-21 09:44:29 +0800
commit115f7408ddaf84bca375ce10b1d99e533c434a47 (patch)
tree9ca3e9dcd39d699c2ef4a8049466ad6fe8f4f63d
parent9cc6e36325f921f2caa4ba7f0c00a8ab4ae88cf9 (diff)
downloadedk2-115f7408ddaf84bca375ce10b1d99e533c434a47.tar.gz
edk2-115f7408ddaf84bca375ce10b1d99e533c434a47.tar.bz2
edk2-115f7408ddaf84bca375ce10b1d99e533c434a47.zip
NetworkPkg: Check for the max DHCP packet length before use it.
This patch updates the PXE and HTTP boot driver to drop the input DHCP packet if it exceed the maximum length. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Fu Siyuan <siyuan.fu@intel.com> Reviewed-By: Wu Jiaxin <jiaxin.wu@intel.com> (cherry picked from commit 632dcfd6857b6211ce3fe9755d3c11e74ef5d447)
-rw-r--r--NetworkPkg/HttpBootDxe/HttpBootDhcp4.h4
-rw-r--r--NetworkPkg/HttpBootDxe/HttpBootDhcp6.c6
-rw-r--r--NetworkPkg/HttpBootDxe/HttpBootDhcp6.h4
-rw-r--r--NetworkPkg/HttpBootDxe/HttpBootImpl.c4
-rw-r--r--NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c34
-rw-r--r--NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h6
-rw-r--r--NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c29
-rw-r--r--NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h6
-rw-r--r--NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c16
9 files changed, 91 insertions, 18 deletions
diff --git a/NetworkPkg/HttpBootDxe/HttpBootDhcp4.h b/NetworkPkg/HttpBootDxe/HttpBootDhcp4.h
index 2bc46deafd..ffc1725145 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootDhcp4.h
+++ b/NetworkPkg/HttpBootDxe/HttpBootDhcp4.h
@@ -216,10 +216,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 e5cf894714..36f7cf877b 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c
+++ b/NetworkPkg/HttpBootDxe/HttpBootDhcp6.c
@@ -425,6 +425,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 59ca19e464..7670d7fc51 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootDhcp6.h
+++ b/NetworkPkg/HttpBootDxe/HttpBootDhcp6.h
@@ -100,10 +100,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 9ea0d7f95f..c0e5c5b837 100644
--- a/NetworkPkg/HttpBootDxe/HttpBootImpl.c
+++ b/NetworkPkg/HttpBootDxe/HttpBootImpl.c
@@ -61,11 +61,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 587566d4e0..c076f0e1a9 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c
@@ -256,7 +256,7 @@ PxeBcBuildDhcp4Options (
OptList[Index]->OpCode = PXEBC_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]);
@@ -1180,7 +1180,7 @@ PxeBcDhcp4CallBack (
PXEBC_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));
}
@@ -1206,6 +1206,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.
@@ -1213,6 +1221,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.
@@ -1229,6 +1245,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
@@ -1253,6 +1275,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 248dc60d2c..cdfb0f497c 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
@@ -303,10 +303,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 6ad5f5f1ac..e03227c33d 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
@@ -1702,6 +1702,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
//
@@ -1717,6 +1725,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
@@ -1727,6 +1741,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.
//
@@ -1758,6 +1780,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 38bf26564d..7ae6dcfc8b 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
@@ -123,10 +123,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 12e5566a79..82eb88b8b6 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);