]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
ShellPkg: acpiview: GTDT: Validate global pointers before use
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / AcpiParser.c
index 088575d0144becab944b2cfe61e3e0c7f6795f0c..84c5f0468da55477acc96dfd0f949a5908d0f7a5 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   ACPI parser\r
 \r
-  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 **/\r
 \r
 #include <Uefi.h>\r
@@ -21,6 +15,15 @@ STATIC UINT32   gIndent;
 STATIC UINT32   mTableErrorCount;\r
 STATIC UINT32   mTableWarningCount;\r
 \r
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
+\r
+/**\r
+  An ACPI_PARSER array describing the ACPI header.\r
+**/\r
+STATIC CONST ACPI_PARSER AcpiHeaderParser[] = {\r
+  PARSE_ACPI_HEADER (&AcpiHdrInfo)\r
+};\r
+\r
 /**\r
   This function resets the ACPI table error counter to Zero.\r
 **/\r
@@ -114,10 +117,17 @@ VerifyChecksum (
   IN UINT32  Length\r
   )\r
 {\r
-  UINTN ByteCount = 0;\r
-  UINT8 Checksum = 0;\r
+  UINTN ByteCount;\r
+  UINT8 Checksum;\r
   UINTN OriginalAttribute;\r
 \r
+  //\r
+  // set local variables to suppress incorrect compiler/analyzer warnings\r
+  //\r
+  OriginalAttribute = 0;\r
+  ByteCount = 0;\r
+  Checksum = 0;\r
+\r
   while (ByteCount < Length) {\r
     Checksum += *(Ptr++);\r
     ByteCount++;\r
@@ -133,7 +143,7 @@ VerifyChecksum (
                          ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))\r
                        );\r
       }\r
-      Print (L"\n\nTable Checksum : OK\n\n");\r
+      Print (L"Table Checksum : OK\n\n");\r
     } else {\r
       IncrementErrorCount ();\r
       if (GetColourHighlighting ()) {\r
@@ -143,7 +153,7 @@ VerifyChecksum (
                          ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))\r
                        );\r
       }\r
-      Print (L"\n\nTable Checksum : FAILED (0x%X)\n\n", Checksum);\r
+      Print (L"Table Checksum : FAILED (0x%X)\n\n", Checksum);\r
     }\r
     if (GetColourHighlighting ()) {\r
       gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);\r
@@ -166,11 +176,14 @@ DumpRaw (
   IN UINT32 Length\r
   )\r
 {\r
-  UINTN ByteCount = 0;\r
+  UINTN ByteCount;\r
   UINTN PartLineChars;\r
-  UINTN AsciiBufferIndex = 0;\r
+  UINTN AsciiBufferIndex;\r
   CHAR8 AsciiBuffer[17];\r
 \r
+  ByteCount = 0;\r
+  AsciiBufferIndex = 0;\r
+\r
   Print (L"Address  : 0x%p\n", Ptr);\r
   Print (L"Length   : %d\n", Length);\r
 \r
@@ -210,7 +223,7 @@ DumpRaw (
 \r
   // Print ASCII data for the final line.\r
   AsciiBuffer[AsciiBufferIndex] = '\0';\r
-  Print (L"  %a", AsciiBuffer);\r
+  Print (L"  %a\n\n", AsciiBuffer);\r
 }\r
 \r
 /**\r
@@ -277,9 +290,12 @@ DumpUint64 (
   // Some fields are not aligned and this causes alignment faults\r
   // on ARM platforms if the compiler generates LDRD instructions.\r
   // Perform word access so that LDRD instructions are not generated.\r
-  UINT64 Val = *(UINT32*)(Ptr + sizeof (UINT32));\r
-  Val <<= 32;\r
-  Val |= *(UINT32*)Ptr;\r
+  UINT64 Val;\r
+\r
+  Val = *(UINT32*)(Ptr + sizeof (UINT32));\r
+\r
+  Val = LShiftU64(Val,32);\r
+  Val |= (UINT64)*(UINT32*)Ptr;\r
 \r
   Print (Format, Val);\r
 }\r
@@ -389,6 +405,39 @@ Dump8Chars (
     );\r
 }\r
 \r
+/**\r
+  This function traces 12 characters which can be optionally\r
+  formated using the format string if specified.\r
+\r
+  If no format string is specified the Format must be NULL.\r
+\r
+  @param [in] Format  Optional format string for tracing the data.\r
+  @param [in] Ptr     Pointer to the start of the buffer.\r
+**/\r
+VOID\r
+EFIAPI\r
+Dump12Chars (\r
+  IN CONST CHAR16* Format OPTIONAL,\r
+  IN       UINT8*  Ptr\r
+  )\r
+{\r
+  Print (\r
+    (Format != NULL) ? Format : L"%c%c%c%c%c%c%c%c%c%c%c%c",\r
+    Ptr[0],\r
+    Ptr[1],\r
+    Ptr[2],\r
+    Ptr[3],\r
+    Ptr[4],\r
+    Ptr[5],\r
+    Ptr[6],\r
+    Ptr[7],\r
+    Ptr[8],\r
+    Ptr[9],\r
+    Ptr[10],\r
+    Ptr[11]\r
+    );\r
+}\r
+\r
 /**\r
   This function indents and prints the ACPI table Field Name.\r
 \r
@@ -456,14 +505,21 @@ ParseAcpi (
 )\r
 {\r
   UINT32  Index;\r
-  UINT32  Offset = 0;\r
+  UINT32  Offset;\r
+  BOOLEAN HighLight;\r
+  UINTN   OriginalAttribute;\r
+\r
+  //\r
+  // set local variables to suppress incorrect compiler/analyzer warnings\r
+  //\r
+  OriginalAttribute = 0;\r
+  Offset = 0;\r
 \r
   // Increment the Indent\r
   gIndent += Indent;\r
 \r
   if (Trace && (AsciiName != NULL)){\r
-    BOOLEAN HighLight = GetColourHighlighting ();\r
-    UINTN   OriginalAttribute;\r
+    HighLight = GetColourHighlighting ();\r
 \r
     if (HighLight) {\r
       OriginalAttribute = gST->ConOut->Mode->Attribute;\r
@@ -487,15 +543,23 @@ ParseAcpi (
 \r
   for (Index = 0; Index < ParserItems; Index++) {\r
     if ((Offset + Parser[Index].Length) > Length) {\r
+\r
+      // For fields outside the buffer length provided, reset any pointers\r
+      // which were supposed to be updated by this function call\r
+      if (Parser[Index].ItemPtr != NULL) {\r
+        *Parser[Index].ItemPtr = NULL;\r
+      }\r
+\r
       // We don't parse past the end of the max length specified\r
-      break;\r
+      continue;\r
     }\r
 \r
-    if (Offset != Parser[Index].Offset) {\r
+    if (GetConsistencyChecking () &&\r
+        (Offset != Parser[Index].Offset)) {\r
       IncrementErrorCount ();\r
       Print (\r
         L"\nERROR: %a: Offset Mismatch for %s\n"\r
-          "CurrentOffset = %d FieldOffset = %d\n",\r
+          L"CurrentOffset = %d FieldOffset = %d\n",\r
         AsciiName,\r
         Parser[Index].NameStr,\r
         Offset,\r
@@ -534,7 +598,8 @@ ParseAcpi (
 \r
         // Validating only makes sense if we are tracing\r
         // the parsed table entries, to report by table name.\r
-        if (Parser[Index].FieldValidator != NULL) {\r
+        if (GetConsistencyChecking () &&\r
+            (Parser[Index].FieldValidator != NULL)) {\r
           Parser[Index].FieldValidator (Ptr, Parser[Index].Context);\r
         }\r
       }\r
@@ -572,23 +637,27 @@ STATIC CONST ACPI_PARSER GasParser[] = {
 \r
   @param [in] Ptr     Pointer to the start of the buffer.\r
   @param [in] Indent  Number of spaces to indent the output.\r
+  @param [in] Length  Length of the GAS structure buffer.\r
+\r
+  @retval Number of bytes parsed.\r
 **/\r
-VOID\r
+UINT32\r
 EFIAPI\r
 DumpGasStruct (\r
   IN UINT8*        Ptr,\r
-  IN UINT32        Indent\r
+  IN UINT32        Indent,\r
+  IN UINT32        Length\r
   )\r
 {\r
   Print (L"\n");\r
-  ParseAcpi (\r
-    TRUE,\r
-    Indent,\r
-    NULL,\r
-    Ptr,\r
-    GAS_LENGTH,\r
-    PARSER_PARAMS (GasParser)\r
-    );\r
+  return ParseAcpi (\r
+           TRUE,\r
+           Indent,\r
+           NULL,\r
+           Ptr,\r
+           Length,\r
+           PARSER_PARAMS (GasParser)\r
+           );\r
 }\r
 \r
 /**\r
@@ -604,7 +673,7 @@ DumpGas (
   IN UINT8*        Ptr\r
   )\r
 {\r
-  DumpGasStruct (Ptr, 2);\r
+  DumpGasStruct (Ptr, 2, GAS_LENGTH);\r
 }\r
 \r
 /**\r
@@ -620,11 +689,6 @@ DumpAcpiHeader (
   IN UINT8* Ptr\r
   )\r
 {\r
-  ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
-  ACPI_PARSER AcpiHeaderParser[] = {\r
-    PARSE_ACPI_HEADER (&AcpiHdrInfo)\r
-  };\r
-\r
   return ParseAcpi (\r
            TRUE,\r
            0,\r
@@ -658,10 +722,6 @@ ParseAcpiHeader (
   )\r
 {\r
   UINT32                        BytesParsed;\r
-  ACPI_DESCRIPTION_HEADER_INFO  AcpiHdrInfo;\r
-  ACPI_PARSER AcpiHeaderParser[] = {\r
-    PARSE_ACPI_HEADER (&AcpiHdrInfo)\r
-  };\r
 \r
   BytesParsed = ParseAcpi (\r
                   FALSE,\r