]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Enhance SmbiosDxe driver:
authorlzeng14 <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 8 May 2012 01:33:23 +0000 (01:33 +0000)
committerlzeng14 <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 8 May 2012 01:33:23 +0000 (01:33 +0000)
1. If string length exceeds 65535 bytes, return error. So infinite loop will not happen because of UINTN overflow.
2. When a SMBIOS entry is added or updated, check if the total length of SMBIOS table exceeds 65535 bytes, if it happens, return error.

Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Elvin Li <elvin.li@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13290 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.c
MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.h

index 2d0be7cd51485f6696573725f6dc4cfebbd382e0..861e35eb9986c96b6ee9d1f770bfb154b06e66f3 100644 (file)
@@ -22,6 +22,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 //\r
 SMBIOS_INSTANCE mPrivateData;\r
 \r
+UINTN mPreAllocatedPages = 0;\r
+\r
 //\r
 // Chassis for SMBIOS entry point structure that is to be installed into EFI system config table.\r
 //\r
@@ -128,6 +130,7 @@ GetSmbiosStructureSize (
 {\r
   UINTN  FullSize;\r
   UINTN  StrLen;\r
+  UINTN  MaxLen;\r
   INT8*  CharInStr;\r
   \r
   if (Size == NULL || NumberOfStrings == NULL) {\r
@@ -149,26 +152,27 @@ GetSmbiosStructureSize (
     }\r
 \r
     if (This->MajorVersion < 2 || (This->MajorVersion == 2 && This->MinorVersion < 7)){\r
-      for (StrLen = 0 ; StrLen < SMBIOS_STRING_MAX_LENGTH; StrLen++) {\r
-        if (*(CharInStr+StrLen) == 0) {\r
-          break;\r
-        }\r
-      }\r
-\r
-      if (StrLen == SMBIOS_STRING_MAX_LENGTH) {\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
+      MaxLen = SMBIOS_STRING_MAX_LENGTH;\r
     } else {\r
       //\r
-      // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string\r
+      // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string.\r
+      // However, the length of the entire structure table (including all strings) must be reported\r
+      // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,\r
+      // which is a WORD field limited to 65,535 bytes.\r
       //\r
-      for (StrLen = 0 ;; StrLen++) {\r
-        if (*(CharInStr+StrLen) == 0) {\r
-          break;\r
-        }\r
+      MaxLen = SMBIOS_TABLE_MAX_LENGTH;\r
+    }\r
+\r
+    for (StrLen = 0 ; StrLen < MaxLen; StrLen++) {\r
+      if (*(CharInStr+StrLen) == 0) {\r
+        break;\r
       }\r
     }\r
 \r
+    if (StrLen == MaxLen) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
     //\r
     // forward the pointer\r
     //\r
@@ -355,6 +359,15 @@ SmbiosAdd (
     return Status;\r
   }\r
 \r
+  if (EntryPointStructure->TableLength + StructureSize > SMBIOS_TABLE_MAX_LENGTH) {\r
+    //\r
+    // The length of the entire structure table (including all strings) must be reported\r
+    // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,\r
+    // which is a WORD field limited to 65,535 bytes.\r
+    //\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
   //\r
   // Enter into critical section\r
   //  \r
@@ -483,13 +496,20 @@ SmbiosUpdateString (
 \r
   InputStrLen = AsciiStrLen(String);\r
 \r
-  //\r
-  // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string\r
-  //\r
   if (This->MajorVersion < 2 || (This->MajorVersion == 2 && This->MinorVersion < 7)) {\r
     if (InputStrLen > SMBIOS_STRING_MAX_LENGTH) {\r
       return EFI_UNSUPPORTED;\r
     }\r
+  } else {\r
+    //\r
+    // Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string.\r
+    // However, the length of the entire structure table (including all strings) must be reported \r
+    // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,\r
+    // which is a WORD field limited to 65,535 bytes.\r
+    //\r
+    if (InputStrLen > SMBIOS_TABLE_MAX_LENGTH) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
   }\r
 \r
   Private = SMBIOS_INSTANCE_FROM_THIS (This);\r
@@ -558,6 +578,15 @@ SmbiosUpdateString (
         return EFI_SUCCESS;\r
       }\r
 \r
+      if (EntryPointStructure->TableLength + InputStrLen - TargetStrLen > SMBIOS_TABLE_MAX_LENGTH) {\r
+        //\r
+        // The length of the entire structure table (including all strings) must be reported\r
+        // in the Structure Table Length field of the SMBIOS Structure Table Entry Point,\r
+        // which is a WORD field limited to 65,535 bytes.\r
+        //\r
+        return EFI_UNSUPPORTED;\r
+      }\r
+\r
       //\r
       // Original string buffer size is not exactly match input string length.\r
       // Re-allocate buffer is needed.\r
@@ -880,7 +909,6 @@ SmbiosCreateTable (
   EFI_SMBIOS_TABLE_HEADER         *SmbiosRecord;\r
   EFI_SMBIOS_TABLE_END_STRUCTURE  EndStructure;\r
   EFI_SMBIOS_ENTRY                *CurrentSmbiosEntry;\r
-  UINTN                           PreAllocatedPages;\r
   \r
   Status            = EFI_SUCCESS;\r
   BufferPointer     = NULL;\r
@@ -890,12 +918,6 @@ SmbiosCreateTable (
   //\r
   SmbiosProtocol = &mPrivateData.Smbios;\r
 \r
-  if (EntryPointStructure->TableAddress == 0) {\r
-    PreAllocatedPages = 0;\r
-  } else {\r
-    PreAllocatedPages = EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength);\r
-  }\r
-\r
   //\r
   // Make some statistics about all the structures\r
   //\r
@@ -938,7 +960,7 @@ SmbiosCreateTable (
     EntryPointStructure->MaxStructureSize = (UINT16) sizeof (EndStructure);\r
   }\r
 \r
-  if ((UINTN) EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength) > PreAllocatedPages) {\r
+  if ((UINTN) EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength) > mPreAllocatedPages) {\r
     //\r
     // If new SMBIOS talbe size exceeds the original pre-allocated page, \r
     // it is time to re-allocate memory (below 4GB).\r
@@ -949,9 +971,10 @@ SmbiosCreateTable (
       //      \r
       FreePages (\r
             (VOID*)(UINTN)EntryPointStructure->TableAddress,\r
-            PreAllocatedPages\r
+            mPreAllocatedPages\r
             );\r
       EntryPointStructure->TableAddress = 0;\r
+      mPreAllocatedPages = 0;\r
     }\r
     \r
     PhysicalAddress = 0xffffffff;\r
@@ -967,6 +990,7 @@ SmbiosCreateTable (
       return EFI_OUT_OF_RESOURCES;\r
     } else {\r
       EntryPointStructure->TableAddress = (UINT32) PhysicalAddress;\r
+      mPreAllocatedPages = EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength);\r
     }\r
   }\r
   \r
@@ -1109,11 +1133,16 @@ SmbiosDriverEntryPoint (
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "SmbiosDriverEntryPoint() could not allocate SMBIOS table < 4GB\n"));\r
     EntryPointStructure->TableAddress = 0;\r
-    EntryPointStructure->TableLength  = 0;\r
   } else {\r
     EntryPointStructure->TableAddress = (UINT32) PhysicalAddress;\r
-    EntryPointStructure->TableLength  = EFI_PAGES_TO_SIZE (1);\r
+    mPreAllocatedPages = 1;\r
   }\r
+\r
+  //\r
+  // Init TableLength to the length of End-Of-Table structure for SmbiosAdd() called at the first time\r
+  // to check the TableLength limitation.\r
+  //\r
+  EntryPointStructure->TableLength  = sizeof (EFI_SMBIOS_TABLE_END_STRUCTURE);\r
   \r
   //\r
   // Make a new handle and install the protocol\r
index 3c78b993bd64d9eaada8fd3c15fbb9b6f570979a..e81b543672f655646a0066a4bcd17957da959f8a 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   This code supports the implementation of the Smbios protocol\r
   \r
-Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\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
@@ -31,6 +31,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/PcdLib.h>\r
 \r
+//\r
+// The length of the entire structure table (including all strings) must be reported\r
+// in the Structure Table Length field of the SMBIOS Structure Table Entry Point,\r
+// which is a WORD field limited to 65,535 bytes.\r
+//\r
+#define SMBIOS_TABLE_MAX_LENGTH 0xFFFF\r
+\r
 #define SMBIOS_INSTANCE_SIGNATURE SIGNATURE_32 ('S', 'B', 'i', 's')\r
 typedef struct {\r
   UINT32                Signature;\r