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:
Doug Flick
2024-01-26 05:54:50 +08:00
committed by mergify[bot]
parent 6f77463d72
commit 4df0229ef9
3 changed files with 171 additions and 11 deletions

View File

@@ -56,13 +56,48 @@ VOID
VOID *Context
);
//
// Per RFC8200 Section 4.2
//
// Two of the currently-defined extension headers -- the Hop-by-Hop
// Options header and the Destination Options header -- carry a variable
// number of type-length-value (TLV) encoded "options", of the following
// format:
//
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
// | Option Type | Opt Data Len | Option Data
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- - - - - - - - -
//
// Option Type 8-bit identifier of the type of option.
//
// Opt Data Len 8-bit unsigned integer. Length of the Option
// Data field of this option, in octets.
//
// Option Data Variable-length field. Option-Type-specific
// data.
//
typedef struct _IP6_OPTION_HEADER {
///
/// identifier of the type of option.
///
UINT8 Type;
///
/// Length of the Option Data field of this option, in octets.
///
UINT8 Length;
///
/// Option-Type-specific data.
///
} IP6_OPTION_HEADER;
STATIC_ASSERT (sizeof (IP6_OPTION_HEADER) == 2, "IP6_OPTION_HEADER is expected to be exactly 2 bytes long.");
#define IP6_NEXT_OPTION_OFFSET(offset, length) (offset + sizeof(IP6_OPTION_HEADER) + length)
STATIC_ASSERT (
IP6_NEXT_OPTION_OFFSET (0, 0) == 2,
"The next option is minimally the combined size of the option tag and length"
);
typedef struct _IP6_ETHE_ADDR_OPTION {
UINT8 Type;
UINT8 Length;