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;
|
SMBIOS_INSTANCE mPrivateData;
|
||||||
|
|
||||||
|
UINTN mPreAllocatedPages = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Chassis for SMBIOS entry point structure that is to be installed into EFI system config table.
|
// Chassis for SMBIOS entry point structure that is to be installed into EFI system config table.
|
||||||
//
|
//
|
||||||
|
@ -128,6 +130,7 @@ GetSmbiosStructureSize (
|
||||||
{
|
{
|
||||||
UINTN FullSize;
|
UINTN FullSize;
|
||||||
UINTN StrLen;
|
UINTN StrLen;
|
||||||
|
UINTN MaxLen;
|
||||||
INT8* CharInStr;
|
INT8* CharInStr;
|
||||||
|
|
||||||
if (Size == NULL || NumberOfStrings == NULL) {
|
if (Size == NULL || NumberOfStrings == NULL) {
|
||||||
|
@ -149,26 +152,27 @@ GetSmbiosStructureSize (
|
||||||
}
|
}
|
||||||
|
|
||||||
if (This->MajorVersion < 2 || (This->MajorVersion == 2 && This->MinorVersion < 7)){
|
if (This->MajorVersion < 2 || (This->MajorVersion == 2 && This->MinorVersion < 7)){
|
||||||
for (StrLen = 0 ; StrLen < SMBIOS_STRING_MAX_LENGTH; StrLen++) {
|
MaxLen = SMBIOS_STRING_MAX_LENGTH;
|
||||||
if (*(CharInStr+StrLen) == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StrLen == SMBIOS_STRING_MAX_LENGTH) {
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
// Reference SMBIOS 2.7, chapter 6.1.3, it will have no limit on the length of each individual text string
|
// 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.
|
||||||
//
|
//
|
||||||
for (StrLen = 0 ;; StrLen++) {
|
MaxLen = SMBIOS_TABLE_MAX_LENGTH;
|
||||||
if (*(CharInStr+StrLen) == 0) {
|
}
|
||||||
break;
|
|
||||||
}
|
for (StrLen = 0 ; StrLen < MaxLen; StrLen++) {
|
||||||
|
if (*(CharInStr+StrLen) == 0) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (StrLen == MaxLen) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// forward the pointer
|
// forward the pointer
|
||||||
//
|
//
|
||||||
|
@ -355,6 +359,15 @@ SmbiosAdd (
|
||||||
return Status;
|
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
|
// Enter into critical section
|
||||||
//
|
//
|
||||||
|
@ -483,13 +496,20 @@ SmbiosUpdateString (
|
||||||
|
|
||||||
InputStrLen = AsciiStrLen(String);
|
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 (This->MajorVersion < 2 || (This->MajorVersion == 2 && This->MinorVersion < 7)) {
|
||||||
if (InputStrLen > SMBIOS_STRING_MAX_LENGTH) {
|
if (InputStrLen > SMBIOS_STRING_MAX_LENGTH) {
|
||||||
return EFI_UNSUPPORTED;
|
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);
|
Private = SMBIOS_INSTANCE_FROM_THIS (This);
|
||||||
|
@ -558,6 +578,15 @@ SmbiosUpdateString (
|
||||||
return EFI_SUCCESS;
|
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.
|
// Original string buffer size is not exactly match input string length.
|
||||||
// Re-allocate buffer is needed.
|
// Re-allocate buffer is needed.
|
||||||
|
@ -880,7 +909,6 @@ SmbiosCreateTable (
|
||||||
EFI_SMBIOS_TABLE_HEADER *SmbiosRecord;
|
EFI_SMBIOS_TABLE_HEADER *SmbiosRecord;
|
||||||
EFI_SMBIOS_TABLE_END_STRUCTURE EndStructure;
|
EFI_SMBIOS_TABLE_END_STRUCTURE EndStructure;
|
||||||
EFI_SMBIOS_ENTRY *CurrentSmbiosEntry;
|
EFI_SMBIOS_ENTRY *CurrentSmbiosEntry;
|
||||||
UINTN PreAllocatedPages;
|
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
BufferPointer = NULL;
|
BufferPointer = NULL;
|
||||||
|
@ -890,12 +918,6 @@ SmbiosCreateTable (
|
||||||
//
|
//
|
||||||
SmbiosProtocol = &mPrivateData.Smbios;
|
SmbiosProtocol = &mPrivateData.Smbios;
|
||||||
|
|
||||||
if (EntryPointStructure->TableAddress == 0) {
|
|
||||||
PreAllocatedPages = 0;
|
|
||||||
} else {
|
|
||||||
PreAllocatedPages = EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Make some statistics about all the structures
|
// Make some statistics about all the structures
|
||||||
//
|
//
|
||||||
|
@ -938,7 +960,7 @@ SmbiosCreateTable (
|
||||||
EntryPointStructure->MaxStructureSize = (UINT16) sizeof (EndStructure);
|
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,
|
// If new SMBIOS talbe size exceeds the original pre-allocated page,
|
||||||
// it is time to re-allocate memory (below 4GB).
|
// it is time to re-allocate memory (below 4GB).
|
||||||
|
@ -949,9 +971,10 @@ SmbiosCreateTable (
|
||||||
//
|
//
|
||||||
FreePages (
|
FreePages (
|
||||||
(VOID*)(UINTN)EntryPointStructure->TableAddress,
|
(VOID*)(UINTN)EntryPointStructure->TableAddress,
|
||||||
PreAllocatedPages
|
mPreAllocatedPages
|
||||||
);
|
);
|
||||||
EntryPointStructure->TableAddress = 0;
|
EntryPointStructure->TableAddress = 0;
|
||||||
|
mPreAllocatedPages = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalAddress = 0xffffffff;
|
PhysicalAddress = 0xffffffff;
|
||||||
|
@ -967,6 +990,7 @@ SmbiosCreateTable (
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
} else {
|
} else {
|
||||||
EntryPointStructure->TableAddress = (UINT32) PhysicalAddress;
|
EntryPointStructure->TableAddress = (UINT32) PhysicalAddress;
|
||||||
|
mPreAllocatedPages = EFI_SIZE_TO_PAGES (EntryPointStructure->TableLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1109,11 +1133,16 @@ SmbiosDriverEntryPoint (
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
DEBUG ((EFI_D_ERROR, "SmbiosDriverEntryPoint() could not allocate SMBIOS table < 4GB\n"));
|
DEBUG ((EFI_D_ERROR, "SmbiosDriverEntryPoint() could not allocate SMBIOS table < 4GB\n"));
|
||||||
EntryPointStructure->TableAddress = 0;
|
EntryPointStructure->TableAddress = 0;
|
||||||
EntryPointStructure->TableLength = 0;
|
|
||||||
} else {
|
} else {
|
||||||
EntryPointStructure->TableAddress = (UINT32) PhysicalAddress;
|
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
|
// Make a new handle and install the protocol
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
This code supports the implementation of the Smbios protocol
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
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/UefiBootServicesTableLib.h>
|
||||||
#include <Library/PcdLib.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')
|
#define SMBIOS_INSTANCE_SIGNATURE SIGNATURE_32 ('S', 'B', 'i', 's')
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT32 Signature;
|
UINT32 Signature;
|
||||||
|
|
Loading…
Reference in New Issue