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>
This commit is contained in:
Fu Siyuan
2016-11-16 13:37:15 +08:00
parent 4f6b33b460
commit 632dcfd685
9 changed files with 91 additions and 18 deletions

View File

@@ -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.