]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
ShellPkg: acpiview: IORT: Validate global pointers before use
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Iort / IortParser.c
index f1cdb9ac01d848f22ab588d8f824886387c5983d..9d5d937c7b2c19945ca2ad3eba644bdfc09cc3f6 100644 (file)
@@ -5,7 +5,7 @@
   SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
   @par Reference(s):\r
-    - IO Remapping Table, Platform Design Document, Revision C, 15 May 2017\r
+    - IO Remapping Table, Platform Design Document, Revision D, March 2018\r
 **/\r
 \r
 #include <IndustryStandard/IoRemappingTable.h>\r
@@ -193,7 +193,9 @@ STATIC CONST ACPI_PARSER IortNodeSmmuV3Parser[] = {
   {L"Event", 4, 44, L"0x%x", NULL, NULL, NULL, NULL},\r
   {L"PRI", 4, 48, L"0x%x", NULL, NULL, NULL, NULL},\r
   {L"GERR", 4, 52, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"Sync", 4, 56, L"0x%x", NULL, NULL, NULL, NULL}\r
+  {L"Sync", 4, 56, L"0x%x", NULL, NULL, NULL, NULL},\r
+  {L"Proximity domain", 4, 60, L"0x%x", NULL, NULL, NULL, NULL},\r
+  {L"Device ID mapping index", 4, 64, L"%d", NULL, NULL, NULL, NULL}\r
 };\r
 \r
 /**\r
@@ -231,7 +233,9 @@ STATIC CONST ACPI_PARSER IortNodeRootComplexParser[] = {
   PARSE_IORT_NODE_HEADER (NULL, NULL),\r
   {L"Memory access properties", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},\r
   {L"ATS Attribute", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},\r
-  {L"PCI Segment number", 4, 28, L"0x%x", NULL, NULL, NULL, NULL}\r
+  {L"PCI Segment number", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},\r
+  {L"Memory access size limit", 1, 32, L"0x%x", NULL, NULL, NULL, NULL},\r
+  {L"Reserved", 3, 33, L"%x %x %x", Dump3Chars, NULL, NULL, NULL}\r
 };\r
 \r
 /**\r
@@ -239,9 +243,10 @@ STATIC CONST ACPI_PARSER IortNodeRootComplexParser[] = {
 **/\r
 STATIC CONST ACPI_PARSER IortNodePmcgParser[] = {\r
   PARSE_IORT_NODE_HEADER (ValidatePmcgIdMappingCount, NULL),\r
-  {L"Base Address", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},\r
+  {L"Page 0 Base Address", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},\r
   {L"Overflow interrupt GSIV", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},\r
   {L"Node reference", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},\r
+  {L"Page 1 Base Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL}\r
 };\r
 \r
 /**\r
@@ -317,6 +322,20 @@ DumpIortNodeSmmuV1V2 (
     PARSER_PARAMS (IortNodeSmmuV1V2Parser)\r
     );\r
 \r
+  // Check if the values used to control the parsing logic have been\r
+  // successfully read.\r
+  if ((InterruptContextCount == NULL)   ||\r
+      (InterruptContextOffset == NULL)  ||\r
+      (PmuInterruptCount == NULL)       ||\r
+      (PmuInterruptOffset == NULL)) {\r
+    IncrementErrorCount ();\r
+    Print (\r
+      L"ERROR: Insufficient SMMUv1/2 node length. Length = %d\n",\r
+      Length\r
+      );\r
+    return;\r
+  }\r
+\r
   Offset = *InterruptContextOffset;\r
   Index = 0;\r
 \r
@@ -428,6 +447,17 @@ DumpIortNodeIts (
             PARSER_PARAMS (IortNodeItsParser)\r
             );\r
 \r
+  // Check if the values used to control the parsing logic have been\r
+  // successfully read.\r
+  if (ItsCount == NULL) {\r
+    IncrementErrorCount ();\r
+    Print (\r
+      L"ERROR: Insufficient ITS group length. Length = %d.\n",\r
+      Length\r
+      );\r
+    return;\r
+  }\r
+\r
   Index = 0;\r
 \r
   while ((Index < *ItsCount) &&\r
@@ -612,6 +642,18 @@ ParseAcpiIort (
     PARSER_PARAMS (IortParser)\r
     );\r
 \r
+  // Check if the values used to control the parsing logic have been\r
+  // successfully read.\r
+  if ((IortNodeCount == NULL) ||\r
+      (IortNodeOffset == NULL)) {\r
+    IncrementErrorCount ();\r
+    Print (\r
+      L"ERROR: Insufficient table length. AcpiTableLength = %d.\n",\r
+      AcpiTableLength\r
+      );\r
+    return;\r
+  }\r
+\r
   Offset = *IortNodeOffset;\r
   NodePtr = Ptr + Offset;\r
   Index = 0;\r
@@ -630,6 +672,21 @@ ParseAcpiIort (
       PARSER_PARAMS (IortNodeHeaderParser)\r
       );\r
 \r
+    // Check if the values used to control the parsing logic have been\r
+    // successfully read.\r
+    if ((IortNodeType == NULL)        ||\r
+        (IortNodeLength == NULL)      ||\r
+        (IortIdMappingCount == NULL)  ||\r
+        (IortIdMappingOffset == NULL)) {\r
+      IncrementErrorCount ();\r
+      Print (\r
+        L"ERROR: Insufficient remaining table buffer length to read the " \\r
+          L"IORT node header. Length = %d.\n",\r
+        AcpiTableLength - Offset\r
+        );\r
+      return;\r
+    }\r
+\r
     // Make sure the IORT Node is inside the table\r
     if ((Offset + (*IortNodeLength)) > AcpiTableLength) {\r
       IncrementErrorCount ();\r