NetworkPkg: Ip6Dxe: SECURITY PATCH CVE-2023-45232 Patch
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4537 REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4538 Bug Details: PixieFail Bug #4 CVE-2023-45232 CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop') Infinite loop when parsing unknown options in the Destination Options header PixieFail Bug #5 CVE-2023-45233 CVSS 7.5 : CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H CWE-835 Loop with Unreachable Exit Condition ('Infinite Loop') Infinite loop when parsing a PadN option in the Destination Options header Change Overview: Most importantly this change corrects the following incorrect math and cleans up the code. > // It is a PadN option > // > - Offset = (UINT8)(Offset + *(Option + Offset + 1) + 2); > + OptDataLen = ((EFI_IP6_OPTION *)(Option + Offset))->Length; > + Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); > case Ip6OptionSkip: > - Offset = (UINT8)(Offset + *(Option + Offset + 1)); > OptDataLen = ((EFI_IP6_OPTION *)(Option + Offset))->Length; > Offset = IP6_NEXT_OPTION_OFFSET (Offset, OptDataLen); Additionally, this change also corrects incorrect math where the calling function was calculating the HDR EXT optionLen as a uint8 instead of a uint16 > - OptionLen = (UINT8)((*Option + 1) * 8 - 2); > + OptionLen = IP6_HDR_EXT_LEN (*Option) - IP6_COMBINED_SIZE_OF_NEXT_HDR_AND_LEN; Additionally this check adds additional logic to santize the incoming data Cc: Saloni Kasbekar <saloni.kasbekar@intel.com> Cc: Zachary Clark-williams <zachary.clark-williams@intel.com> Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com> Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
This commit is contained in:
@@ -12,6 +12,77 @@
|
||||
|
||||
#define IP6_FRAGMENT_OFFSET_MASK (~0x3)
|
||||
|
||||
//
|
||||
// For more information see RFC 8200, Section 4.3, 4.4, and 4.6
|
||||
//
|
||||
// This example format is from section 4.6
|
||||
// This does not apply to fragment headers
|
||||
//
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
// | Next Header | Hdr Ext Len | |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
|
||||
// | |
|
||||
// . .
|
||||
// . Header-Specific Data .
|
||||
// . .
|
||||
// | |
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
//
|
||||
// Next Header 8-bit selector. Identifies the type of
|
||||
// header immediately following the extension
|
||||
// header. Uses the same values as the IPv4
|
||||
// Protocol field [IANA-PN].
|
||||
//
|
||||
// Hdr Ext Len 8-bit unsigned integer. Length of the
|
||||
// Destination Options header in 8-octet units,
|
||||
// not including the first 8 octets.
|
||||
|
||||
//
|
||||
// These defines apply to the following:
|
||||
// 1. Hop by Hop
|
||||
// 2. Routing
|
||||
// 3. Destination
|
||||
//
|
||||
typedef struct _IP6_EXT_HDR {
|
||||
///
|
||||
/// The Next Header field identifies the type of header immediately
|
||||
///
|
||||
UINT8 NextHeader;
|
||||
///
|
||||
/// The Hdr Ext Len field specifies the length of the Hop-by-Hop Options
|
||||
///
|
||||
UINT8 HdrExtLen;
|
||||
///
|
||||
/// Header-Specific Data
|
||||
///
|
||||
} IP6_EXT_HDR;
|
||||
|
||||
STATIC_ASSERT (
|
||||
sizeof (IP6_EXT_HDR) == 2,
|
||||
"The combined size of Next Header and Len is two 8 bit fields"
|
||||
);
|
||||
|
||||
//
|
||||
// IPv6 extension headers contain an 8-bit length field which describes the size of
|
||||
// the header. However, the length field only includes the size of the extension
|
||||
// header options, not the size of the first 8 bytes of the header. Therefore, in
|
||||
// order to calculate the full size of the extension header, we add 1 (to account
|
||||
// for the first 8 bytes omitted by the length field reporting) and then multiply
|
||||
// by 8 (since the size is represented in 8-byte units).
|
||||
//
|
||||
// a is the length field of the extension header (UINT8)
|
||||
// The result may be up to 2046 octets (UINT16)
|
||||
//
|
||||
#define IP6_HDR_EXT_LEN(a) (((UINT16)((UINT8)(a)) + 1) * 8)
|
||||
|
||||
// This is the maxmimum length permissible by a extension header
|
||||
// Length is UINT8 of 8 octets not including the first 8 octets
|
||||
#define IP6_MAX_EXT_DATA_LENGTH (IP6_HDR_EXT_LEN (MAX_UINT8) - sizeof(IP6_EXT_HDR))
|
||||
STATIC_ASSERT (
|
||||
IP6_MAX_EXT_DATA_LENGTH == 2046,
|
||||
"Maximum data length is ((MAX_UINT8 + 1) * 8) - 2"
|
||||
);
|
||||
|
||||
typedef struct _IP6_FRAGMENT_HEADER {
|
||||
UINT8 NextHeader;
|
||||
UINT8 Reserved;
|
||||
|
Reference in New Issue
Block a user