From nobody Wed May 1 22:00:41 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+43649+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1562914500; cv=none; d=zoho.com; s=zohoarc; b=ADbdrmVxKBgsOQFkxMaqAZDXks4wxbGtsjcapRHvJLLRSZoDAoJIsZCi/4cUNGueRro302WCDUKQqqwzYFWezyI/sgbs7ZYBOA4vHBU0UIsjsTCV+DCLKfV33oXiV42rLtxm0skelDdisGEYHKMHUokSJuxOrlxoSENyUrlbRzQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1562914500; h=Content-Type:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To:ARC-Authentication-Results; bh=TwokXja43Ta+Y0nI6vHGetJ1GTsI/bX/3KCOUPucDe0=; b=feedoovghpbSq7su71ROk8IHkF0p9nICrLM6rQSQwdX+3Q8Ntr0ir72q5GHDX0wq44KqUn2c34Gzh4MNLIWT1Bg9NkMSIsvk17YCmdwh/VyBAUlu1PgR4xxBJ/wFP5cKVnVd5O4mvogRKEXqP1SEqO95tb0cCtUBASeuK8vz+8k= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+43649+1787277+3901457@groups.io Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 156291450056479.31006255905265; Thu, 11 Jul 2019 23:55:00 -0700 (PDT) Return-Path: X-Received: from EUR04-HE1-obe.outbound.protection.outlook.com (EUR04-HE1-obe.outbound.protection.outlook.com [40.107.7.48]) by groups.io with SMTP; Thu, 11 Jul 2019 23:54:59 -0700 X-Received: from VI1PR08CA0178.eurprd08.prod.outlook.com (2603:10a6:800:d1::32) by AM0PR08MB4947.eurprd08.prod.outlook.com (2603:10a6:208:158::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2052.17; Fri, 12 Jul 2019 06:54:54 +0000 X-Received: from DB5EUR03FT010.eop-EUR03.prod.protection.outlook.com (2a01:111:f400:7e0a::207) by VI1PR08CA0178.outlook.office365.com (2603:10a6:800:d1::32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.2073.11 via Frontend Transport; Fri, 12 Jul 2019 06:54:54 +0000 Received-SPF: pass (zoho.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+43649+1787277+3901457@groups.io; helo=web01.groups.io; Received-SPF: TempError (protection.outlook.com: error in processing during lookup of arm.com: DNS Timeout) X-Received: from nebula.arm.com (40.67.248.234) by DB5EUR03FT010.mail.protection.outlook.com (10.152.20.96) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.20.2052.18 via Frontend Transport; Fri, 12 Jul 2019 06:54:52 +0000 X-Received: from AZ-NEU-EX01.Emea.Arm.com (10.251.26.4) by AZ-NEU-EX04.Arm.com (10.251.24.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.1415.2; Fri, 12 Jul 2019 06:53:22 +0000 X-Received: from AZ-NEU-EX03.Arm.com (10.251.24.31) by AZ-NEU-EX01.Emea.Arm.com (10.251.26.4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1415.2; Fri, 12 Jul 2019 06:53:22 +0000 X-Received: from E119924.Arm.com (10.37.8.167) by mail.arm.com (10.251.24.31) with Microsoft SMTP Server id 15.1.1415.2 via Frontend Transport; Fri, 12 Jul 2019 06:53:21 +0000 From: "Krzysztof Koch" To: CC: , , , , , Subject: [edk2-devel] [PATCH v1 09/11] ShellPkg: acpiview: IORT: Add error-checking in the parsing logic Date: Fri, 12 Jul 2019 07:52:41 +0100 Message-ID: <20190712065243.3812-10-krzysztof.koch@arm.com> In-Reply-To: <20190712065243.3812-1-krzysztof.koch@arm.com> References: <20190712065243.3812-1-krzysztof.koch@arm.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d4eeaf44-afa4-463d-3444-08d70695d75f X-MS-TrafficTypeDiagnostic: AM0PR08MB4947: X-MS-Exchange-PUrlCount: 1 X-Microsoft-Antispam-PRVS: NoDisclaimer: True X-MS-Oob-TLC-OOBClassifiers: OLM:7219; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Message-Info: tEwwAdAuTTBs1+F7AuFzqlUZQqh5shBKsFq+Ui3XrdeE53l+McZ1dmQNSyosUMTP5U7LmfEshXGksz2/Ny/i8fL6qLlVJ7kTmHx3D3pgn7P8ECxdptU5FLoFvCOp0LneMHmPjUqpAEyeZfW/VCeMZv9nSvCUHceszBw2H42QVx0l7Tm0Dvi/tJCrQG4X+0iVUz8l8hNcO8lNuX4PUe3i2tqy1ASyb6MSg7ADTSnJn3iqshNOgfx0EtxtqCjN17eNAGbGATARoREEaHrYo7hp0WAQWoQrXb9VhNSm+JtIdcN0X5fghn5jinmft4FF/KmvsqxN34HfsnfQXOr5Z1qEHnVPkdRg4/r7r7nykJX4pLIKns6UQEGbXo9zssVkUW8kop7ebmSBeY43kQ25BG07nboRT4H35rSqRolCsL9E+SM= X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jul 2019 06:54:52.9328 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d4eeaf44-afa4-463d-3444-08d70695d75f X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d;Ip=[40.67.248.234];Helo=[nebula.arm.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR08MB4947 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,krzysztof.koch@arm.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1562914500; bh=iwBHNwoAvpZnAspOc8WKagxNwcHVYXkshgMLbfRIWRQ=; h=CC:Content-Type:Date:From:Reply-To:Subject:To; b=RbI17oGowT5I+gXiIT5sgetQbaQzcpOIKGDdQADip49/ddgzQUXNYpfFPnhsCJ1VNX0 oLqOVx4DsqG9WcY1FyfL4OBrQB9dFqED4CZxc04A4B26qenMUT9kUswnWXWItdK3zcqbN aOp3V9lFK+jFaQG2GsNobhEY3f/YEdKgudU= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 1. Check if the global pointers (in the scope of this ACPI table parser) have been successfully updated before they are later used to control the parsing logic. 2. Remove redundant forward function declarations by repositioning blocks of code. 3. Test against buffer overruns. 4. Allow silencing ACPI table content validation errors which do not cause table parsing to fail. 5. Move ID mapping count validation for the PMCG node to the IortNodePmcgParser[] ACPI_PARSER array. This check does not affect the flow of IORT parsing and is limited to a single table field in scope. Signed-off-by: Krzysztof Koch Reviewed-by: Alexei Fedorov --- Changes can be seen at: https://github.com/KrzysztofKoch1/edk2/commit/0b398= f116f7aed99dbec4090b5c2c0ed93273ef7 Notes: v1: - improve the logic in the IORT parser [Krzysztof] ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c | 4= 19 +++++++++++++------- 1 file changed, 279 insertions(+), 140 deletions(-) diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/Iort= Parser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortPa= rser.c index 93f78e1a9786ed53f6b5529f478b72a220b4f8df..f09e7aeeb34bf4c3d9564240b53= 539c8d6811f66 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c @@ -13,6 +13,7 @@ #include #include "AcpiParser.h" #include "AcpiTableParser.h" +#include "AcpiView.h" =20 // Local variables STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; @@ -45,7 +46,35 @@ EFIAPI ValidateItsIdMappingCount ( IN UINT8* Ptr, IN VOID* Context - ); + ) +{ + if (*(UINT32*)Ptr !=3D 0) { + IncrementErrorCount (); + Print (L"\nERROR: IORT ID Mapping count must be zero."); + } +} + +/** + This function validates the ID Mapping array count for the Performance + Monitoring Counter Group (PMCG) node. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidatePmcgIdMappingCount ( + IN UINT8* Ptr, + IN VOID* Context + ) +{ + if (*(UINT32*)Ptr > 1) { + IncrementErrorCount (); + Print (L"\nERROR: IORT ID Mapping count must not be greater than 1."); + } +} =20 /** This function validates the ID Mapping array offset for the ITS node. @@ -60,7 +89,13 @@ EFIAPI ValidateItsIdArrayReference ( IN UINT8* Ptr, IN VOID* Context - ); + ) +{ + if (*(UINT32*)Ptr !=3D 0) { + IncrementErrorCount (); + Print (L"\nERROR: IORT ID Mapping offset must be zero."); + } +} =20 /** Helper Macro for populating the IORT Node header in the ACPI_PARSER arra= y. @@ -204,95 +239,65 @@ STATIC CONST ACPI_PARSER IortNodeRootComplexParser[] = =3D { An ACPI_PARSER array describing the IORT PMCG node. **/ STATIC CONST ACPI_PARSER IortNodePmcgParser[] =3D { - PARSE_IORT_NODE_HEADER (NULL, NULL), + PARSE_IORT_NODE_HEADER (ValidatePmcgIdMappingCount, NULL), {L"Base Address", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL}, {L"Overflow interrupt GSIV", 4, 24, L"0x%x", NULL, NULL, NULL, NULL}, {L"Node reference", 4, 28, L"0x%x", NULL, NULL, NULL, NULL}, }; =20 -/** - This function validates the ID Mapping array count for the ITS node. - - @param [in] Ptr Pointer to the start of the field data. - @param [in] Context Pointer to context specific information e.g. this - could be a pointer to the ACPI table header. -**/ -STATIC -VOID -EFIAPI -ValidateItsIdMappingCount ( - IN UINT8* Ptr, - IN VOID* Context - ) -{ - if (*(UINT32*)Ptr !=3D 0) { - IncrementErrorCount (); - Print (L"\nERROR: IORT ID Mapping count must be zero."); - } -} - -/** - This function validates the ID Mapping array offset for the ITS node. - - @param [in] Ptr Pointer to the start of the field data. - @param [in] Context Pointer to context specific information e.g. this - could be a pointer to the ACPI table header. -**/ -STATIC -VOID -EFIAPI -ValidateItsIdArrayReference ( - IN UINT8* Ptr, - IN VOID* Context - ) -{ - if (*(UINT32*)Ptr !=3D 0) { - IncrementErrorCount (); - Print (L"\nERROR: IORT ID Mapping offset must be zero."); - } -} - /** This function parses the IORT Node Id Mapping array. =20 - @param [in] Ptr Pointer to the start of the IORT Table. + @param [in] Ptr Pointer to the start of the ID mapping array. + @param [in] Length Length of the buffer. @param [in] MappingCount The ID Mapping count. - @param [in] MappingOffset The offset of the ID Mapping array - from the start of the IORT table. **/ STATIC VOID DumpIortNodeIdMappings ( IN UINT8* Ptr, - IN UINT32 MappingCount, - IN UINT32 MappingOffset + IN UINT32 Length, + IN UINT32 MappingCount ) { - UINT8* IdMappingPtr; UINT32 Index; UINT32 Offset; CHAR8 Buffer[40]; // Used for AsciiName param of ParseAcpi =20 - IdMappingPtr =3D Ptr + MappingOffset; Index =3D 0; - while (Index < MappingCount) { + Offset =3D 0; + + while ((Index < MappingCount) && + (Offset < Length)) { AsciiSPrint ( Buffer, sizeof (Buffer), "ID Mapping [%d]", Index ); - Offset =3D ParseAcpi ( - TRUE, - 4, - Buffer, - IdMappingPtr, - 20, - PARSER_PARAMS (IortNodeIdMappingParser) - ); - IdMappingPtr +=3D Offset; + Offset +=3D ParseAcpi ( + TRUE, + 4, + Buffer, + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (IortNodeIdMappingParser) + ); Index++; } + + // Cross-check the substructure count with the length of the encapsulati= ng + // buffer + if (GetConsistencyChecking () && + (Index < MappingCount)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid ID Mapping Count. IdMappingCount =3D %d. " \ + L"IdMappingBufferSize =3D %d.\n", + MappingCount, + Length + ); + } } =20 /** @@ -317,8 +322,6 @@ DumpIortNodeSmmuV1V2 ( UINT32 Offset; CHAR8 Buffer[50]; // Used for AsciiName param of ParseAcpi =20 - UINT8* ArrayPtr; - ParseAcpi ( TRUE, 2, @@ -328,51 +331,97 @@ DumpIortNodeSmmuV1V2 ( PARSER_PARAMS (IortNodeSmmuV1V2Parser) ); =20 - ArrayPtr =3D Ptr + *InterruptContextOffset; + // Check if the values used to control the parsing logic have been + // successfully read. + if ((InterruptContextCount =3D=3D NULL) || + (InterruptContextOffset =3D=3D NULL) || + (PmuInterruptCount =3D=3D NULL) || + (PmuInterruptOffset =3D=3D NULL)) { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient SMMUv1/2 node length. Length =3D %d\n", + Length + ); + return; + } + + Offset =3D *InterruptContextOffset; Index =3D 0; - while (Index < *InterruptContextCount) { + + while ((Index < *InterruptContextCount) && + (Offset < Length)) { AsciiSPrint ( Buffer, sizeof (Buffer), "Context Interrupts Array [%d]", Index ); - Offset =3D ParseAcpi ( - TRUE, - 4, - Buffer, - ArrayPtr, - 8, - PARSER_PARAMS (InterruptArrayParser) - ); - ArrayPtr +=3D Offset; + Offset +=3D ParseAcpi ( + TRUE, + 4, + Buffer, + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (InterruptArrayParser) + ); Index++; } =20 - ArrayPtr =3D Ptr + *PmuInterruptOffset; + // Cross-check the substructure count with the length of the encapsulati= ng + // buffer + if (GetConsistencyChecking () && + (Index < *InterruptContextCount)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Context Interrupt count. InterruptContextCount =3D = %d. " \ + L"SMMUv1v2BufferSize =3D %d.\n", + *InterruptContextCount, + Length + ); + return; + } + + Offset =3D *PmuInterruptOffset; Index =3D 0; - while (Index < *PmuInterruptCount) { + + while ((Index < *PmuInterruptCount) && + (Offset < Length)) { AsciiSPrint ( Buffer, sizeof (Buffer), "PMU Interrupts Array [%d]", Index ); - Offset =3D ParseAcpi ( - TRUE, - 4, - Buffer, - ArrayPtr, - 8, - PARSER_PARAMS (InterruptArrayParser) - ); - ArrayPtr +=3D Offset; + Offset +=3D ParseAcpi ( + TRUE, + 4, + Buffer, + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (InterruptArrayParser) + ); Index++; } =20 - if (*IortIdMappingCount !=3D 0) { - DumpIortNodeIdMappings (Ptr, MappingCount, MappingOffset); + // Cross-check the substructure count with the length of the encapsulati= ng + // buffer + if (GetConsistencyChecking () && + (Index < *PmuInterruptCount)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid PMU Interrupt count. PmuInterruptCount =3D %d. " \ + L"SMMUv1v2BufferSize =3D %d.\n", + *PmuInterruptCount, + Length + ); + return; } + + DumpIortNodeIdMappings ( + Ptr + MappingOffset, + Length - MappingOffset, + MappingCount + ); } =20 /** @@ -402,9 +451,11 @@ DumpIortNodeSmmuV3 ( PARSER_PARAMS (IortNodeSmmuV3Parser) ); =20 - if (*IortIdMappingCount !=3D 0) { - DumpIortNodeIdMappings (Ptr, MappingCount, MappingOffset); - } + DumpIortNodeIdMappings ( + Ptr + MappingOffset, + Length - MappingOffset, + MappingCount + ); } =20 /** @@ -422,40 +473,64 @@ DumpIortNodeIts ( { UINT32 Offset; UINT32 Index; - UINT8* ItsIdPtr; CHAR8 Buffer[80]; // Used for AsciiName param of ParseAcpi =20 Offset =3D ParseAcpi ( - TRUE, - 2, - "ITS Node", - Ptr, - Length, - PARSER_PARAMS (IortNodeItsParser) - ); + TRUE, + 2, + "ITS Node", + Ptr, + Length, + PARSER_PARAMS (IortNodeItsParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if (ItsCount =3D=3D NULL) { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient ITS group length. Length =3D %d.\n", + Length + ); + return; + } =20 - ItsIdPtr =3D Ptr + Offset; Index =3D 0; - while (Index < *ItsCount) { + + while ((Index < *ItsCount) && + (Offset < Length)) { AsciiSPrint ( Buffer, sizeof (Buffer), "GIC ITS Identifier Array [%d]", Index ); - Offset =3D ParseAcpi ( - TRUE, - 4, - Buffer, - ItsIdPtr, - 4, - PARSER_PARAMS (ItsIdParser) - ); - ItsIdPtr +=3D Offset; + Offset +=3D ParseAcpi ( + TRUE, + 4, + Buffer, + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (ItsIdParser) + ); Index++; } =20 + // Cross-check the substructure count with the length of the encapsulati= ng + // buffer + if (GetConsistencyChecking () && + (Index < *ItsCount)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid GIC ITS identifier count. ItsCount =3D %d. " \ + L"ItsGroupBufferSize =3D %d.\n", + *ItsCount, + Length + ); + } + // Note: ITS does not have the ID Mappings Array + } =20 /** @@ -478,8 +553,6 @@ DumpIortNodeNamedComponent ( { UINT32 Offset; UINT32 Index; - UINT8* DeviceNamePtr; - UINT32 DeviceNameLength; =20 Offset =3D ParseAcpi ( TRUE, @@ -490,19 +563,35 @@ DumpIortNodeNamedComponent ( PARSER_PARAMS (IortNodeNamedComponentParser) ); =20 - DeviceNamePtr =3D Ptr + Offset; // Estimate the Device Name length - DeviceNameLength =3D Length - Offset - (MappingCount * 20); PrintFieldName (2, L"Device Object Name"); Index =3D 0; - while ((Index < DeviceNameLength) && (DeviceNamePtr[Index] !=3D 0)) { - Print (L"%c", DeviceNamePtr[Index++]); + + while ((*(Ptr + Offset) !=3D 0) && + (Offset < Length)) { + Print (L"%c", *(Ptr + Offset)); + Offset++; } Print (L"\n"); =20 - if (*IortIdMappingCount !=3D 0) { - DumpIortNodeIdMappings (Ptr, MappingCount, MappingOffset); + // Cross-check the string length with the size of the encapsulating + // buffer + if (GetConsistencyChecking () && + (*(Ptr + Offset) !=3D '\0')) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Device object name string. " \ + L"NamedComponentBufferSize =3D %d.\n", + Length + ); + return; } + + DumpIortNodeIdMappings ( + Ptr + MappingOffset, + Length - MappingOffset, + MappingCount + ); } =20 /** @@ -532,9 +621,11 @@ DumpIortNodeRootComplex ( PARSER_PARAMS (IortNodeRootComplexParser) ); =20 - if (*IortIdMappingCount !=3D 0) { - DumpIortNodeIdMappings (Ptr, MappingCount, MappingOffset); - } + DumpIortNodeIdMappings ( + Ptr + MappingOffset, + Length - MappingOffset, + MappingCount + ); } =20 /** @@ -562,19 +653,13 @@ DumpIortNodePmcg ( Ptr, Length, PARSER_PARAMS (IortNodePmcgParser) - ); + ); =20 - if (*IortIdMappingCount !=3D 0) { - DumpIortNodeIdMappings (Ptr, MappingCount, MappingOffset); - } - - if (*IortIdMappingCount > 1) { - IncrementErrorCount (); - Print ( - L"ERROR: ID mapping must not be greater than 1. Id Mapping Count =3D= %d\n", - *IortIdMappingCount - ); - } + DumpIortNodeIdMappings ( + Ptr + MappingOffset, + Length - MappingOffset, + MappingCount + ); } =20 /** @@ -621,23 +706,61 @@ ParseAcpiIort ( AcpiTableLength, PARSER_PARAMS (IortParser) ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((IortNodeCount =3D=3D NULL) || + (IortNodeOffset =3D=3D NULL)) { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient table length. AcpiTableLength =3D %d.\n", + AcpiTableLength + ); + return; + } + Offset =3D *IortNodeOffset; NodePtr =3D Ptr + Offset; Index =3D 0; =20 - while ((Index < *IortNodeCount) && (Offset < AcpiTableLength)) { + // Parse the specified number of IORT nodes or the IORT table buffer len= gth. + // Whichever is minimum. + while ((Index++ < *IortNodeCount) && + (Offset < AcpiTableLength)) { // Parse the IORT Node Header ParseAcpi ( FALSE, 0, "IORT Node Header", NodePtr, - 16, + AcpiTableLength - Offset, PARSER_PARAMS (IortNodeHeaderParser) ); - if (*IortNodeLength =3D=3D 0) { + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((IortNodeType =3D=3D NULL) || + (IortNodeLength =3D=3D NULL) || + (IortIdMappingCount =3D=3D NULL) || + (IortIdMappingOffset =3D=3D NULL)) { IncrementErrorCount (); - Print (L"ERROR: Parser error. Invalid table data.\n"); + Print ( + L"ERROR: Insufficient remaining table buffer length to read the " \ + L"IORT node header. Length =3D %d.\n", + AcpiTableLength - Offset + ); + return; + } + + // Make sure the IORT Node is inside the table + if ((Offset + (*IortNodeLength)) > AcpiTableLength) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid IORT node length. IortNodeLength =3D %d. " \ + L"RemainingTableBufferLength =3D %d. IORT parsing aborted.\n", + *IortNodeLength, + AcpiTableLength - Offset + ); return; } =20 @@ -689,15 +812,31 @@ ParseAcpiIort ( *IortNodeLength, *IortIdMappingCount, *IortIdMappingOffset - ); + ); break; =20 default: - IncrementErrorCount (); - Print (L"ERROR: Unsupported IORT Node type =3D %d\n", *IortNodeTyp= e); + if (GetConsistencyChecking ()) { + IncrementErrorCount (); + Print (L"ERROR: Unsupported IORT Node type =3D %d\n", *IortNodeT= ype); + } + break; } // switch =20 NodePtr +=3D (*IortNodeLength); Offset +=3D (*IortNodeLength); } // while + + // Cross-check the substructure count with the length of the encapsulati= ng + // buffer + if (GetConsistencyChecking () && + (Index < *IortNodeCount)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid IORT node count. IortNodeCount =3D %d. " \ + L"AcpiTableLength =3D %d.\n", + *IortNodeCount, + AcpiTableLength + ); + } } -- 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)' -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#43649): https://edk2.groups.io/g/devel/message/43649 Mute This Topic: https://groups.io/mt/32439513/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-