OcSmbiosLib: Cleanup & refactor OEM value exposure

This commit is contained in:
vit9696 2021-02-13 10:03:04 +03:00
parent d8f9b5575a
commit f51fee6f9e
5 changed files with 162 additions and 122 deletions

View File

@ -31,6 +31,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
#define OC_SMBIOS_VENDOR_NAME "Acidanthera"
//
// Maximum characters for valid Mac-like OEM name.
//
#define OC_SMBIOS_OEM_NAME_MAX 48
typedef struct OC_SMBIOS_MEMORY_DEVICE_DATA_ {
//
// Strings.
@ -86,8 +91,9 @@ typedef struct OC_SMBIOS_DATA_ {
//
// Type 16
//
UINT16 MemoryDevicesCount;
BOOLEAN HasCustomMemory;
CONST UINT8 *MemoryErrorCorrection;
UINT16 MemoryDevicesCount;
CONST UINT64 *MemoryMaxCapacity;
//
// Type 17
@ -212,36 +218,76 @@ OcSmbiosTableFree (
IN OUT OC_SMBIOS_TABLE *Table
);
/**
Create new SMBIOS based on specified overrides.
@param[in,out] SmbiosTable SMBIOS Table handle.
@param[in] Data SMBIOS overrides.
@param[in] Mode SMBIOS update mode.
@param[in] CpuInfo CPU information.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
OcSmbiosCreate (
IN OUT OC_SMBIOS_TABLE *SmbiosTable,
IN OC_SMBIOS_DATA *Data,
IN OC_SMBIOS_UPDATE_MODE Mode,
IN OC_CPU_INFO *CpuInfo,
IN BOOLEAN UseCustomMemory
IN OC_CPU_INFO *CpuInfo
);
/**
Extract OEM information from SMBIOS to different places.
@param[in,out] SmbiosTable SMBIOS Table handle.
@param[out] ProductName Export SMBIOS Type 1 product name,
requiring OC_SMBIOS_OEM_NAME_MAX bytes.
@param[in] UseVariableStorage Export OEM information to NVRAM.
**/
VOID
OcSmbiosExposeOemInfo (
IN OC_SMBIOS_TABLE *SmbiosTable
OcSmbiosExtractOemInfo (
IN OC_SMBIOS_TABLE *SmbiosTable,
OUT CHAR8 *ProductName OPTIONAL,
IN BOOLEAN UseVariableStorage
);
/**
Convert SMC revision from SMC REV key format (6-byte)
to SMBIOS ASCII format (16-byte, APPLE_SMBIOS_SMC_VERSION_SIZE).
@param[in] SmcRevision SMC revision in REV key format.
@param[out] SmcVersion SMC revision in SMBIOS format.
**/
VOID
OcSmbiosGetSmcVersion (
IN CONST UINT8 *SmcRevision,
OUT UINT8 *SmcVersion
);
CHAR8*
OcSmbiosGetManufacturer (
IN OC_SMBIOS_TABLE *SmbiosTable
/**
Choose update mode based on default representation.
Always returns valid update mode, by falling back
to Create when unknown mode was found. Known modes are:
TryOverwrite, Create, Overwrite, Custom.
@param[in] UpdateMode in ASCII format.
@returns SMBIS update mode in enum format.
**/
OC_SMBIOS_UPDATE_MODE
OcSmbiosGetUpdateMode (
IN CONST CHAR8 *UpdateMode
);
CHAR8*
OcSmbiosGetProductName (
IN OC_SMBIOS_TABLE *SmbiosTable
);
/**
Dump current SMBIOS data into specified directory
under EntryV#.bin/DataV#.bin names, where # is
SMBIOS version: 1, 3, or both.
@param[in] Root Directory to dump SMBIOS data.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
OcSmbiosDump (
IN EFI_FILE_PROTOCOL *Root

View File

@ -33,7 +33,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Guid/AppleVariable.h>
STATIC CHAR8 mCurrentSmbiosProductName[48];
STATIC CHAR8 mCurrentSmbiosProductName[OC_SMBIOS_OEM_NAME_MAX];
STATIC
VOID
@ -414,6 +414,8 @@ OcPlatformUpdateSmbios (
// Inject custom memory info.
//
if (Config->PlatformInfo.CustomMemory) {
Data.HasCustomMemory = TRUE;
if (Config->PlatformInfo.Memory.Devices.Count <= MAX_UINT16) {
Data.MemoryDevicesCount = (UINT16) Config->PlatformInfo.Memory.Devices.Count;
} else {
@ -435,7 +437,7 @@ OcPlatformUpdateSmbios (
Data.MemoryDevicesCount = 0;
}
for (Index = 0; Index < Data.MemoryDevicesCount; Index++) {
for (Index = 0; Index < Data.MemoryDevicesCount; ++Index) {
MemoryEntry = Config->PlatformInfo.Memory.Devices.Values[Index];
Data.MemoryDevices[Index].AssetTag = OC_BLOB_GET (&MemoryEntry->AssetTag);
@ -458,7 +460,7 @@ OcPlatformUpdateSmbios (
}
}
Status = OcSmbiosCreate (SmbiosTable, &Data, UpdateMode, CpuInfo, Config->PlatformInfo.CustomMemory);
Status = OcSmbiosCreate (SmbiosTable, &Data, UpdateMode, CpuInfo);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "OC: Failed to update SMBIOS - %r\n", Status));
}
@ -689,14 +691,12 @@ OcLoadPlatformSupport (
IN OC_CPU_INFO *CpuInfo
)
{
CONST CHAR8 *SmbiosUpdateStr;
OC_SMBIOS_UPDATE_MODE SmbiosUpdateMode;
MAC_INFO_DATA InfoData;
MAC_INFO_DATA *UsedMacInfo;
EFI_STATUS Status;
OC_SMBIOS_TABLE SmbiosTable;
BOOLEAN ExposeOem;
CONST CHAR8 *SmbiosProductName;
if (Config->PlatformInfo.Automatic) {
GetMacInfo (OC_BLOB_GET (&Config->PlatformInfo.Generic.SystemProductName), &InfoData);
@ -705,43 +705,28 @@ OcLoadPlatformSupport (
UsedMacInfo = NULL;
}
if (Config->PlatformInfo.UpdateDataHub) {
OcPlatformUpdateDataHub (Config, CpuInfo, UsedMacInfo);
}
ExposeOem = (Config->Misc.Security.ExposeSensitiveData & OCS_EXPOSE_OEM_INFO) != 0;
if (ExposeOem || Config->PlatformInfo.UpdateSmbios) {
Status = OcSmbiosTablePrepare (&SmbiosTable);
if (!EFI_ERROR (Status)) {
if (ExposeOem) {
OcSmbiosExposeOemInfo (&SmbiosTable);
}
SmbiosProductName = OcSmbiosGetProductName (&SmbiosTable);
DEBUG ((DEBUG_INFO, "OC: Current SMBIOS: %a model %a\n", OcSmbiosGetManufacturer (&SmbiosTable), SmbiosProductName));
Status = AsciiStrCpyS (mCurrentSmbiosProductName, sizeof (mCurrentSmbiosProductName), SmbiosProductName);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OC: Failed to copy SMBIOS product name %a\n", SmbiosProductName));
}
OcSmbiosExtractOemInfo (
&SmbiosTable,
mCurrentSmbiosProductName,
ExposeOem
);
if (Config->PlatformInfo.UpdateSmbios) {
SmbiosUpdateStr = OC_BLOB_GET (&Config->PlatformInfo.UpdateSmbiosMode);
if (AsciiStrCmp (SmbiosUpdateStr, "TryOverwrite") == 0) {
SmbiosUpdateMode = OcSmbiosUpdateTryOverwrite;
} else if (AsciiStrCmp (SmbiosUpdateStr, "Create") == 0) {
SmbiosUpdateMode = OcSmbiosUpdateCreate;
} else if (AsciiStrCmp (SmbiosUpdateStr, "Overwrite") == 0) {
SmbiosUpdateMode = OcSmbiosUpdateOverwrite;
} else if (AsciiStrCmp (SmbiosUpdateStr, "Custom") == 0) {
SmbiosUpdateMode = OcSmbiosUpdateCustom;
} else {
DEBUG ((DEBUG_WARN, "OC: Invalid SMBIOS update mode %a\n", SmbiosUpdateStr));
SmbiosUpdateMode = OcSmbiosUpdateCreate;
}
OcPlatformUpdateSmbios (Config, CpuInfo, UsedMacInfo, &SmbiosTable, SmbiosUpdateMode);
SmbiosUpdateMode = OcSmbiosGetUpdateMode (
OC_BLOB_GET (&Config->PlatformInfo.UpdateSmbiosMode)
);
OcPlatformUpdateSmbios (
Config,
CpuInfo,
UsedMacInfo,
&SmbiosTable,
SmbiosUpdateMode
);
}
OcSmbiosTableFree (&SmbiosTable);
@ -750,6 +735,10 @@ OcLoadPlatformSupport (
}
}
if (Config->PlatformInfo.UpdateDataHub) {
OcPlatformUpdateDataHub (Config, CpuInfo, UsedMacInfo);
}
if (Config->PlatformInfo.UpdateNvram) {
OcPlatformUpdateNvram (Config, UsedMacInfo);
}

View File

@ -1783,13 +1783,37 @@ OcSmbiosGetSmcVersion (
}
}
OC_SMBIOS_UPDATE_MODE
OcSmbiosGetUpdateMode (
IN CONST CHAR8 *UpdateMode
)
{
if (AsciiStrCmp (UpdateMode, "TryOverwrite") == 0) {
return OcSmbiosUpdateTryOverwrite;
}
if (AsciiStrCmp (UpdateMode, "Create") == 0) {
return OcSmbiosUpdateCreate;
}
if (AsciiStrCmp (UpdateMode, "Overwrite") == 0) {
return OcSmbiosUpdateOverwrite;
}
if (AsciiStrCmp (UpdateMode, "Custom") == 0) {
return OcSmbiosUpdateCustom;
}
DEBUG ((DEBUG_INFO, "OCSMB: Invalid SMBIOS update mode %a\n", UpdateMode));
return OcSmbiosUpdateCreate;
}
EFI_STATUS
OcSmbiosCreate (
IN OUT OC_SMBIOS_TABLE *SmbiosTable,
IN OC_SMBIOS_DATA *Data,
IN OC_SMBIOS_UPDATE_MODE Mode,
IN OC_CPU_INFO *CpuInfo,
IN BOOLEAN UseCustomMemory
IN OC_CPU_INFO *CpuInfo
)
{
EFI_STATUS Status;
@ -1837,7 +1861,7 @@ OcSmbiosCreate (
// Create new memory tables if custom memory is desired.
// Otherwise we'll patch the existing memory information.
//
if (UseCustomMemory) {
if (Data->HasCustomMemory) {
CreateMemoryArray (
SmbiosTable,
Data,
@ -1979,107 +2003,88 @@ OcSmbiosCreate (
}
VOID
OcSmbiosExposeOemInfo (
IN OC_SMBIOS_TABLE *SmbiosTable
OcSmbiosExtractOemInfo (
IN OC_SMBIOS_TABLE *SmbiosTable,
OUT CHAR8 *ProductName OPTIONAL,
IN BOOLEAN UseVariableStorage
)
{
EFI_STATUS Status;
CONST CHAR8 *SmProductName;
CONST CHAR8 *SmManufacturer;
CONST CHAR8 *SmBoard;
APPLE_SMBIOS_STRUCTURE_POINTER Original;
CHAR8 *Value;
UINTN Length;
SmProductName = NULL;
SmManufacturer = NULL;
SmBoard = NULL;
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_SYSTEM_INFORMATION, 1);
if (Original.Raw != NULL && SMBIOS_ACCESSIBLE (Original, Standard.Type1->ProductName)) {
Value = SmbiosGetString (Original, Original.Standard.Type1->ProductName);
if (Value != NULL) {
Length = AsciiStrLen (Value);
SmProductName = SmbiosGetString (Original, Original.Standard.Type1->ProductName);
}
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_BASEBOARD_INFORMATION, 1);
if (Original.Raw != NULL) {
if (SMBIOS_ACCESSIBLE (Original, Standard.Type2->Manufacturer)) {
SmManufacturer = SmbiosGetString (Original, Original.Standard.Type2->Manufacturer);
}
if (SMBIOS_ACCESSIBLE (Original, Standard.Type2->ProductName)) {
SmBoard = SmbiosGetString (Original, Original.Standard.Type2->ProductName);
}
}
DEBUG ((
DEBUG_INFO,
"OCSMB: Current SMBIOS %a (%a made by %a)\n",
SmProductName,
SmBoard,
SmManufacturer
));
if (ProductName != NULL && SmProductName != NULL) {
Status = AsciiStrCpyS (ProductName, OC_SMBIOS_OEM_NAME_MAX, SmProductName);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OC: Failed to copy SMBIOS product name %a\n", SmProductName));
}
}
if (UseVariableStorage) {
if (SmProductName != NULL) {
Status = gRT->SetVariable (
OC_OEM_PRODUCT_VARIABLE_NAME,
&gOcVendorVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
Length,
Value
AsciiStrLen (SmProductName),
(VOID *) SmProductName
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCSMB: Cannot write OEM product\n"));
}
} else {
DEBUG ((DEBUG_INFO, "OCSMB: Cannot find OEM product\n"));
}
} else {
DEBUG ((DEBUG_INFO, "OCSMB: Cannot access OEM Type1\n"));
}
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_BASEBOARD_INFORMATION, 1);
if (Original.Raw != NULL
&& SMBIOS_ACCESSIBLE (Original, Standard.Type2->Manufacturer)
&& SMBIOS_ACCESSIBLE (Original, Standard.Type2->ProductName)) {
Value = SmbiosGetString (Original, Original.Standard.Type2->Manufacturer);
if (Value != NULL) {
Length = AsciiStrLen (Value);
if (SmManufacturer != NULL && SmBoard != NULL) {
Status = gRT->SetVariable (
OC_OEM_VENDOR_VARIABLE_NAME,
&gOcVendorVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
Length,
Value
AsciiStrLen (SmManufacturer),
(VOID *) SmManufacturer
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCSMB: Cannot write OEM vendor\n"));
DEBUG ((DEBUG_INFO, "OCSMB: Cannot write OEM board manufacturer - %r\n", Status));
}
} else {
DEBUG ((DEBUG_INFO, "OCSMB: Cannot find OEM vendor\n"));
}
Value = SmbiosGetString (Original, Original.Standard.Type2->ProductName);
if (Value != NULL) {
Length = AsciiStrLen (Value);
Status = gRT->SetVariable (
OC_OEM_BOARD_VARIABLE_NAME,
&gOcVendorVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
Length,
Value
AsciiStrLen (SmBoard),
(VOID *) SmBoard
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCSMB: Cannot write OEM board\n"));
DEBUG ((DEBUG_INFO, "OCSMB: Cannot write OEM board - %r\n", Status));
}
} else {
DEBUG ((DEBUG_INFO, "OCSMB: Cannot find OEM board\n"));
}
} else {
DEBUG ((DEBUG_INFO, "OCSMB: Cannot access OEM Type2\n"));
}
}
CHAR8*
OcSmbiosGetManufacturer (
IN OC_SMBIOS_TABLE *SmbiosTable
)
{
APPLE_SMBIOS_STRUCTURE_POINTER Original;
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_SYSTEM_INFORMATION, 1);
if (Original.Raw != NULL && SMBIOS_ACCESSIBLE (Original, Standard.Type1->Manufacturer)) {
return SmbiosGetString (Original, Original.Standard.Type1->Manufacturer);
}
return NULL;
}
CHAR8*
OcSmbiosGetProductName (
IN OC_SMBIOS_TABLE *SmbiosTable
)
{
APPLE_SMBIOS_STRUCTURE_POINTER Original;
Original = SmbiosGetOriginalStructure (SMBIOS_TYPE_SYSTEM_INFORMATION, 1);
if (Original.Raw != NULL && SMBIOS_ACCESSIBLE (Original, Standard.Type1->ProductName)) {
return SmbiosGetString (Original, Original.Standard.Type1->ProductName);
}
return NULL;
}

View File

@ -90,7 +90,7 @@ TestSmbios (
OcCpuScanProcessor (&CpuInfo);
Status = OcSmbiosTablePrepare (&SmbiosTable);
if (!EFI_ERROR (Status)) {
OcSmbiosCreate (&SmbiosTable, &Data, OcSmbiosUpdateCreate, &CpuInfo, FALSE);
OcSmbiosCreate (&SmbiosTable, &Data, OcSmbiosUpdateCreate, &CpuInfo);
OcSmbiosTableFree (&SmbiosTable);
}

View File

@ -96,7 +96,7 @@ int ENTRY_POINT(int argc, char** argv) {
OC_SMBIOS_TABLE SmbiosTable;
Status = OcSmbiosTablePrepare (&SmbiosTable);
if (!EFI_ERROR (Status)) {
Status = OcSmbiosCreate (&SmbiosTable, &SmbiosData, OcSmbiosUpdateCreate, &CpuInfo, FALSE);
Status = OcSmbiosCreate (&SmbiosTable, &SmbiosData, OcSmbiosUpdateCreate, &CpuInfo);
if (!EFI_ERROR (Status)) {
SMBIOS_TABLE_3_0_ENTRY_POINT *patchedTablePtr = NULL;
Status = EfiGetSystemConfigurationTable (&gEfiSmbios3TableGuid, (VOID **) &patchedTablePtr);
@ -141,7 +141,7 @@ INT32 LLVMFuzzerTestOneInput(CONST UINT8 *Data, UINTN Size) {
OC_SMBIOS_TABLE SmbiosTable;
Status = OcSmbiosTablePrepare (&SmbiosTable);
if (!EFI_ERROR (Status)) {
OcSmbiosCreate (&SmbiosTable, &SmbiosData, OcSmbiosUpdateCreate, &CpuInfo, FALSE);
OcSmbiosCreate (&SmbiosTable, &SmbiosData, OcSmbiosUpdateCreate, &CpuInfo);
OcSmbiosTableFree (&SmbiosTable);
}