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