From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mx.groups.io with SMTP id smtpd.web09.5673.1581924947071746967 for ; Sun, 16 Feb 2020 23:35:47 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.100, mailfrom: jiaxin.wu@intel.com) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Feb 2020 23:35:46 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.70,451,1574150400"; d="scan'208";a="228330964" Received: from jiaxinwu-mobl.ccr.corp.intel.com ([10.255.31.28]) by orsmga008.jf.intel.com with ESMTP; 16 Feb 2020 23:35:45 -0800 From: "Wu, Jiaxin" To: devel@edk2.groups.io Cc: Fu Siyuan , Wu Jiaxin Subject: [PATCH v1] MdeModulePkg/Ip4Dxe: Check the received package length (CVE-2019-14559). Date: Mon, 17 Feb 2020 15:35:41 +0800 Message-Id: <20200217073541.13920-1-Jiaxin.wu@intel.com> X-Mailer: git-send-email 2.16.2.windows.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch is to check the received package length to make sure the package has a valid length field. Cc: Fu Siyuan Cc:Maciej Rabeda Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Wu Jiaxin Reviewed-by: Siyuan Fu --- NetworkPkg/Ip4Dxe/Ip4Input.c | 46 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/NetworkPkg/Ip4Dxe/Ip4Input.c b/NetworkPkg/Ip4Dxe/Ip4Input.c index fec242c71f..3fd08a5231 100644 --- a/NetworkPkg/Ip4Dxe/Ip4Input.c +++ b/NetworkPkg/Ip4Dxe/Ip4Input.c @@ -1,9 +1,9 @@ /** @file IP4 input process. -Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.
(C) Copyright 2015 Hewlett-Packard Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -709,14 +709,10 @@ Ip4PreProcessPacket ( UINT16 Checksum; // // Check if the IP4 header is correctly formatted. // - if ((*Packet)->TotalSize < IP4_MIN_HEADLEN) { - return EFI_INVALID_PARAMETER; - } - HeadLen = (Head->HeadLen << 2); TotalLen = NTOHS (Head->TotalLen); // // Mnp may deliver frame trailer sequence up, trim it off. @@ -806,10 +802,34 @@ Ip4PreProcessPacket ( } return EFI_SUCCESS; } +/** + This function checks the IPv4 packet length. + + @param[in] Packet Pointer to the IPv4 Packet to be checked. + + @retval TRUE The input IPv4 packet length is valid. + @retval FALSE The input IPv4 packet length is invalid. + +**/ +BOOLEAN +Ip4IsValidPacketLength ( + IN NET_BUF *Packet + ) +{ + // + // Check the IP4 packet length. + // + if (Packet->TotalSize < IP4_MIN_HEADLEN) { + return FALSE; + } + + return TRUE; +} + /** The IP4 input routine. It is called by the IP4_INTERFACE when a IP4 fragment is received from MNP. @param[in] Ip4Instance The IP4 child that request the receive, most like @@ -842,10 +862,14 @@ Ip4AccpetFrame ( if (EFI_ERROR (IoStatus) || (IpSb->State == IP4_SERVICE_DESTROY)) { goto DROP; } + if (!Ip4IsValidPacketLength (Packet)) { + goto RESTART; + } + Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL); ASSERT (Head != NULL); OptionLen = (Head->HeadLen << 2) - IP4_MIN_HEADLEN; if (OptionLen > 0) { Option = (UINT8 *) (Head + 1); @@ -888,14 +912,18 @@ Ip4AccpetFrame ( // // If the packet is protected by tunnel mode, parse the inner Ip Packet. // ZeroMem (&ZeroHead, sizeof (IP4_HEAD)); if (0 == CompareMem (Head, &ZeroHead, sizeof (IP4_HEAD))) { - // Packet may have been changed. Head, HeadLen, TotalLen, and - // info must be reloaded before use. The ownership of the packet - // is transferred to the packet process logic. - // + // Packet may have been changed. Head, HeadLen, TotalLen, and + // info must be reloaded before use. The ownership of the packet + // is transferred to the packet process logic. + // + if (!Ip4IsValidPacketLength (Packet)) { + goto RESTART; + } + Head = (IP4_HEAD *) NetbufGetByte (Packet, 0, NULL); ASSERT (Head != NULL); Status = Ip4PreProcessPacket ( IpSb, &Packet, -- 2.16.2.windows.1