summaryrefslogtreecommitdiff
path: root/Platform/BroxtonPlatformPkg/Common
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2017-06-26 11:31:41 +0800
committerGuo Mang <mang.guo@intel.com>2017-06-26 14:44:22 +0800
commit1ed4dbb91fb42787f8e1aabc33cde6b6c35670f3 (patch)
tree2313bc14417bc8ee8305055105ce6f19aeca9091 /Platform/BroxtonPlatformPkg/Common
parentd9752ad1ddfe4c1a2104327ee5c6a10afaaf220c (diff)
downloadedk2-platforms-1ed4dbb91fb42787f8e1aabc33cde6b6c35670f3.tar.xz
Security of Setup Variable
System can still boot to shell and OS successfully after EFI variable deletion/corruption. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'Platform/BroxtonPlatformPkg/Common')
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/MultiPlatSupport.h201
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.c207
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.h4
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformSetupDxe/PlatformSetupDxe.c38
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformSetupDxe/Vfr.vfr10
5 files changed, 457 insertions, 3 deletions
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/MultiPlatSupport.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/MultiPlatSupport.h
new file mode 100644
index 0000000000..7f21da28ff
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/MultiPlatSupport.h
@@ -0,0 +1,201 @@
+/**@file
+
+Copyright (c) 2016 - 2017, 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
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __MULTI_PLATFORM_SUPPORT_H__
+#define __MULTI_PLATFORM_SUPPORT_H__
+
+extern EFI_GUID gDefaultDataOptSizeFileGuid;
+
+///
+/// Alignment of variable name and data, according to the architecture:
+/// * For IA-32 and Intel(R) 64 architectures: 1.
+/// * For IA-64 architecture: 8.
+///
+#if defined (MDE_CPU_IPF)
+#define ALIGNMENT 8
+#else
+#define ALIGNMENT 1
+#endif
+
+//
+// GET_PAD_SIZE calculates the miminal pad bytes needed to make the current pad size satisfy the alignment requirement.
+//
+#if (ALIGNMENT == 1)
+#define GET_PAD_SIZE(a) (0)
+#else
+#define GET_PAD_SIZE(a) (((~a) + 1) & (ALIGNMENT - 1))
+#endif
+
+///
+/// Alignment of Variable Data Header in Variable Store region.
+///
+#define HEADER_ALIGNMENT 4
+#define HEADER_ALIGN(Header) (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & (~(HEADER_ALIGNMENT - 1)))
+
+///
+/// Status of Variable Store Region.
+///
+/*typedef enum {
+ EfiRaw,
+ EfiValid,
+ EfiInvalid,
+ EfiUnknown
+} VARIABLE_STORE_STATUS;*/
+
+#pragma pack(1)
+
+///
+/// Variable Store Header Format and State.
+///
+#define VARIABLE_STORE_FORMATTED 0x5a
+#define VARIABLE_STORE_HEALTHY 0xfe
+
+///
+/// Variable Store region header.
+///
+/*typedef struct {
+ ///
+ /// Variable store region signature.
+ ///
+ EFI_GUID Signature;
+ ///
+ /// Size of entire variable store,
+ /// including size of variable store header but not including the size of FvHeader.
+ ///
+ UINT32 Size;
+ ///
+ /// Variable region format state.
+ ///
+ UINT8 Format;
+ ///
+ /// Variable region healthy state.
+ ///
+ UINT8 State;
+ UINT16 Reserved;
+ UINT32 Reserved1;
+} VARIABLE_STORE_HEADER;*/
+
+///
+/// Variable data start flag.
+///
+#define VARIABLE_DATA 0x55AA
+
+///
+/// Variable State flags.
+///
+#define VAR_IN_DELETED_TRANSITION 0xfe ///< Variable is in obsolete transition.
+#define VAR_DELETED 0xfd ///< Variable is obsolete.
+#define VAR_HEADER_VALID_ONLY 0x7f ///< Variable header has been valid.
+#define VAR_ADDED 0x3f ///< Variable has been completely added.
+
+///
+/// Single Variable Data Header Structure.
+///
+/*typedef struct {
+ ///
+ /// Variable Data Start Flag.
+ ///
+ UINT16 StartId;
+ ///
+ /// Variable State defined above.
+ ///
+ UINT8 State;
+ UINT8 Reserved;
+ ///
+ /// Attributes of variable defined in UEFI specification.
+ ///
+ UINT32 Attributes;
+ ///
+ /// Size of variable null-terminated Unicode string name.
+ ///
+ UINT32 NameSize;
+ ///
+ /// Size of the variable data without this header.
+ ///
+ UINT32 DataSize;
+ ///
+ /// A unique identifier for the vendor that produces and consumes this varaible.
+ ///
+ EFI_GUID VendorGuid;
+} VARIABLE_HEADER;*/
+
+///
+/// Single Variable Data Header Structure for Auth variable.
+///
+/*typedef struct {
+ ///
+ /// Variable Data Start Flag.
+ ///
+ UINT16 StartId;
+ ///
+ /// Variable State defined above.
+ ///
+ UINT8 State;
+ UINT8 Reserved;
+ ///
+ /// Attributes of variable defined in UEFI specification.
+ ///
+ UINT32 Attributes;
+ ///
+ /// Associated monotonic count value against replay attack.
+ ///
+ UINT64 MonotonicCount;
+ ///
+ /// Associated TimeStamp value against replay attack.
+ ///
+ EFI_TIME TimeStamp;
+ ///
+ /// Index of associated public key in database.
+ ///
+ UINT32 PubKeyIndex;
+ ///
+ /// Size of variable null-terminated Unicode string name.
+ ///
+ UINT32 NameSize;
+ ///
+ /// Size of the variable data without this header.
+ ///
+ UINT32 DataSize;
+ ///
+ /// A unique identifier for the vendor that produces and consumes this varaible.
+ ///
+ EFI_GUID VendorGuid;
+} AUTHENTICATED_VARIABLE_HEADER;*/
+
+typedef struct {
+ UINT16 DefaultId;
+ UINT16 BoardId;
+} DEFAULT_INFO;
+
+typedef struct {
+ UINT16 Offset;
+ UINT8 Value;
+} DATA_DELTA;
+
+typedef struct {
+ //
+ // HeaderSize includes HeaderSize fields and DefaultInfo arrays
+ //
+ UINT16 HeaderSize;
+ //
+ // DefaultInfo arrays those have the same default setting.
+ //
+ DEFAULT_INFO DefaultInfo[1];
+ //
+ // Default data is stored as variable storage or the array of DATA_DELTA.
+ //
+} DEFAULT_DATA;
+
+#pragma pack()
+
+#endif
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.c
index fe454bf89f..49121aed7d 100644
--- a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.c
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.c
@@ -75,6 +75,15 @@
#include <Library/PlatformSecLib.h>
#include <Library/TimerLib.h>
+#include <PiPei.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <MultiPlatSupport.h>
+
+//
+// GUID used in FCE. FCE generate ffs file with this GUID.
+//
+EFI_GUID gDefaultDataOptSizeFileGuid = { 0x003e7b41, 0x98a2, 0x4be2, { 0xb2, 0x7a, 0x6c, 0x30, 0xc7, 0x65, 0x52, 0x25 }};
+
#if (ENBDT_PF_ENABLE == 1)
//
//SSC
@@ -913,6 +922,7 @@ PlatformInitPreMemEntryPoint (
PEI_BOARD_PRE_MEM_INIT_PPI *BoardPreMemInitPpi;
UINTN Instance;
UINT64 AcpiVariableSetCompatibility;
+ UINTN VarSize;
Status = (*PeiServices)->RegisterForShadow (FileHandle);
@@ -1116,6 +1126,29 @@ PlatformInitPreMemEntryPoint (
Tick = CarMap->IbblPerfRecord4;
PERF_END_EX (NULL, "IBBMVer", "IBBL", Tick, 0x1041);
+
+ VarSize = sizeof (SYSTEM_CONFIGURATION);
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ L"Setup",
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VarSize,
+ &SystemConfiguration
+ );
+ if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) {
+ Status = PlatformCreateDefaultVariableHob (EFI_HII_DEFAULT_CLASS_STANDARD);
+ ASSERT_EFI_ERROR (Status);
+ }
+ Status = VariableServices->GetVariable (
+ VariableServices,
+ L"Setup",
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VarSize,
+ &SystemConfiguration
+ );
+ ASSERT_EFI_ERROR (Status);
//
// Normal boot - build Hob for SEC performance data.
//
@@ -1372,3 +1405,177 @@ ReadBxtIPlatformIds (
return EFI_SUCCESS;
}
+
+/**
+Description:
+
+ This function finds the matched default data and create GUID hob for it.
+
+Arguments:
+
+ DefaultId - Specifies the type of defaults to retrieve.
+
+Returns:
+
+ EFI_SUCCESS - The matched default data is found.
+ EFI_NOT_FOUND - The matched default data is not found.
+ EFI_OUT_OF_RESOURCES - No enough resource to create HOB.
+
+**/
+EFI_STATUS
+PlatformCreateDefaultVariableHob (
+ IN UINT16 DefaultId
+ )
+
+{
+ UINTN FvInstance;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ EFI_FFS_FILE_HEADER *FfsHeader;
+ UINT32 FileSize;
+ EFI_COMMON_SECTION_HEADER *Section;
+ UINT32 SectionLength;
+ BOOLEAN DefaultSettingIsFound;
+ DEFAULT_DATA *DefaultData;
+ DEFAULT_INFO *DefaultInfo;
+ VARIABLE_STORE_HEADER *VarStoreHeader;
+ VARIABLE_STORE_HEADER *VarStoreHeaderHob;
+ UINT8 *VarHobPtr;
+ UINT8 *VarPtr;
+ UINT32 VarDataOffset;
+ UINT32 VarHobDataOffset;
+ BOOLEAN IsFirstSection;
+ DATA_DELTA *DataDelta;
+ UINTN DataDeltaSize;
+ UINTN Index;
+ CONST EFI_PEI_SERVICES **PeiServices;
+
+ //
+ // Get PeiService pointer
+ //
+ PeiServices = GetPeiServicesTablePointer ();
+
+ //
+ // Find the FFS file that stores all default data.
+ //
+ DefaultSettingIsFound = FALSE;
+ FvInstance = 0;
+ FfsHeader = NULL;
+ while (((*PeiServices)->FfsFindNextVolume (PeiServices, FvInstance, (VOID **) &FvHeader) == EFI_SUCCESS) &&
+ (!DefaultSettingIsFound)) {
+ FfsHeader = NULL;
+ while ((*PeiServices)->FfsFindNextFile (PeiServices, EFI_FV_FILETYPE_FREEFORM, FvHeader, (VOID **) &FfsHeader) == EFI_SUCCESS) {
+ if (CompareGuid ((EFI_GUID *) FfsHeader, &gDefaultDataOptSizeFileGuid)) {
+ DefaultSettingIsFound = TRUE;
+ break;
+ }
+ }
+ FvInstance ++;
+ }
+
+ //
+ // FFS file is not found.
+ //
+ if (!DefaultSettingIsFound) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Find the matched default data for the input default ID and plat ID.
+ //
+ DefaultSettingIsFound = FALSE;
+ VarStoreHeaderHob = NULL;
+ VarHobPtr = NULL;
+ DataDelta = NULL;
+ DataDeltaSize = 0;
+ IsFirstSection = TRUE;
+ VarStoreHeader = NULL;
+ Section = (EFI_COMMON_SECTION_HEADER *)(FfsHeader + 1);
+ FileSize = *(UINT32 *)(FfsHeader->Size) & 0x00FFFFFF;
+ while (((UINTN) Section < (UINTN) FfsHeader + FileSize) && !DefaultSettingIsFound) {
+ DefaultData = (DEFAULT_DATA *) (Section + 1);
+ DefaultInfo = &(DefaultData->DefaultInfo[0]);
+ SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
+
+ if (IsFirstSection) {
+ //
+ // Create HOB to store default data so that Variable driver can use it.
+ // Allocate more data for header alignment.
+ //
+ VarStoreHeader = (VARIABLE_STORE_HEADER *) ((UINT8 *) DefaultData + DefaultData->HeaderSize);
+ VarStoreHeaderHob = (VARIABLE_STORE_HEADER *) BuildGuidHob (&VarStoreHeader->Signature, VarStoreHeader->Size + HEADER_ALIGNMENT - 1);
+ if (VarStoreHeaderHob == NULL) {
+ //
+ // No enough hob resource.
+ //
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Copy variable storage header.
+ //
+ CopyMem (VarStoreHeaderHob, VarStoreHeader, sizeof (VARIABLE_STORE_HEADER));
+ //
+ // Copy variable data.
+ //
+ VarPtr = (UINT8 *) HEADER_ALIGN ((UINTN) (VarStoreHeader + 1));
+ VarDataOffset = (UINT32) ((UINTN) VarPtr - (UINTN) VarStoreHeader);
+ VarHobPtr = (UINT8 *) HEADER_ALIGN ((UINTN) (VarStoreHeaderHob + 1));
+ VarHobDataOffset = (UINT32) ((UINTN) VarHobPtr - (UINTN) VarStoreHeaderHob);
+ CopyMem (VarHobPtr, VarPtr, VarStoreHeader->Size - VarDataOffset);
+ //
+ // Update variable size.
+ //
+ VarStoreHeaderHob->Size = VarStoreHeader->Size - VarDataOffset + VarHobDataOffset;
+
+ //
+ // Update Delta Data
+ //
+ VarHobPtr = (UINT8 *) VarStoreHeaderHob - VarDataOffset + VarHobDataOffset;
+ } else {
+ //
+ // Apply delta setting
+ //
+ DataDelta = (DATA_DELTA *) ((UINT8 *) DefaultData + DefaultData->HeaderSize);
+ DataDeltaSize = SectionLength - sizeof (EFI_COMMON_SECTION_HEADER) - DefaultData->HeaderSize;
+ for (Index = 0; Index < DataDeltaSize / sizeof (DATA_DELTA); Index ++) {
+ *((UINT8 *) VarHobPtr + DataDelta[Index].Offset) = DataDelta[Index].Value;
+ }
+ }
+
+ //
+ // Find the matched DefaultId
+ //
+ while ((UINTN) DefaultInfo < (UINTN) DefaultData + DefaultData->HeaderSize) {
+ if (DefaultInfo->DefaultId == DefaultId) {
+ DefaultSettingIsFound = TRUE;
+ break;
+ }
+ DefaultInfo ++;
+ }
+ //
+ // Size is 24 bits wide so mask upper 8 bits.
+ // SectionLength is adjusted it is 4 byte aligned.
+ // Go to the next section
+ //
+ SectionLength = (SectionLength + 3) & (~3);
+ ASSERT (SectionLength != 0);
+ Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
+ IsFirstSection = FALSE;
+ }
+ //
+ // Matched default data is not found.
+ //
+ if (!DefaultSettingIsFound) {
+ //
+ // Change created HOB type to be unused.
+ //
+ if (VarStoreHeaderHob != NULL) {
+ ((EFI_HOB_GUID_TYPE *)((UINT8 *) VarStoreHeaderHob - sizeof (EFI_HOB_GUID_TYPE)))->Header.HobType = EFI_HOB_TYPE_UNUSED;
+ }
+ return EFI_NOT_FOUND;
+ }
+
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.h b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.h
index 17b4dad36d..3aa5033e08 100644
--- a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.h
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformPreMemPei/PlatformInitPreMem.h
@@ -139,5 +139,9 @@ InstallMonoStatusCode (
IN CONST EFI_PEI_SERVICES **PeiServices
);
+EFI_STATUS
+PlatformCreateDefaultVariableHob (
+IN UINT16 DefaultId
+);
#endif
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformSetupDxe/PlatformSetupDxe.c b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformSetupDxe/PlatformSetupDxe.c
index 54c751faaf..ff594965f2 100644
--- a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformSetupDxe/PlatformSetupDxe.c
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformSetupDxe/PlatformSetupDxe.c
@@ -402,6 +402,8 @@ SystemConfigCallback (
CHAR16 *StringBuffer2;
EFI_STATUS Status;
SEC_OPERATION_PROTOCOL *SeCOp;
+ UINTN VariableSize;
+ UINT32 VariableAttributes;
StringBuffer1 = AllocateZeroPool (200 * sizeof (CHAR16));
ASSERT (StringBuffer1 != NULL);
@@ -412,7 +414,43 @@ SystemConfigCallback (
return EFI_OUT_OF_RESOURCES;
}
+ Private = EFI_CALLBACK_INFO_FROM_THIS (This);
+ FakeNvData = &Private->FakeNvData;
+
switch (Action) {
+ case EFI_BROWSER_ACTION_FORM_OPEN:
+ {
+ if (KeyValue == 0x1003) {
+ if (!HiiGetBrowserData (&mSystemConfigGuid, mVariableName, sizeof (SYSTEM_CONFIGURATION), (UINT8 *) FakeNvData)) {
+ return EFI_NOT_FOUND;
+ }
+
+ CheckSystemConfigLoad (FakeNvData);
+
+ //
+ // Pass changed uncommitted data back to Form Browser
+ //
+ HiiSetBrowserData (&mSystemConfigGuid, mVariableName, sizeof (SYSTEM_CONFIGURATION), (UINT8 *) FakeNvData, NULL);
+ }
+ break;
+ }
+ case EFI_BROWSER_ACTION_SUBMITTED:
+ {
+ if (KeyValue == 0x1002) {
+ VariableSize = sizeof (SYSTEM_CONFIGURATION);
+ Status = gRT->GetVariable (
+ L"Setup",
+ &gEfiSetupVariableGuid,
+ &VariableAttributes,
+ &VariableSize,
+ FakeNvData
+ );
+ if (!EFI_ERROR (Status)) {
+ CheckSystemConfigSave (FakeNvData);
+ }
+ }
+ break;
+ }
case EFI_BROWSER_ACTION_CHANGING:
case EFI_BROWSER_ACTION_CHANGED:
{
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformSetupDxe/Vfr.vfr b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformSetupDxe/Vfr.vfr
index 4b10a49bfe..5e5b4facb6 100644
--- a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformSetupDxe/Vfr.vfr
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformSetupDxe/Vfr.vfr
@@ -16,6 +16,9 @@
#include "PlatformSetupDxeStrDefs.h"
#include "Guid/SetupVariable.h"
+#define EFI_VARIABLE_NON_VOLATILE 0x00000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
formset
guid = SYSTEM_CONFIGURATION_GUID,
@@ -24,8 +27,7 @@ formset
class = 1,
subclass = 0,
-
- varstore SYSTEM_CONFIGURATION, name = Setup, guid = SYSTEM_CONFIGURATION_GUID;
+ efivarstore SYSTEM_CONFIGURATION, attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS, name = Setup, guid = SYSTEM_CONFIGURATION_GUID;
form formid = ROOT_FORM_ID,
title = STRING_TOKEN(STR_SYSTEM_SETUP_TITLE);
@@ -34,7 +36,9 @@ formset
//
goto ROOT_MAIN_FORM_ID,
prompt = STRING_TOKEN(STR_MAIN_TITLE),
- help = STRING_TOKEN(STR_MAIN_HELP);
+ help = STRING_TOKEN(STR_MAIN_HELP),
+ flags = INTERACTIVE, // INTERACTIVE indicate it's marked with EFI_IFR_FLAG_CALLBACK
+ key = 0x1003; // Question ID which will be passed-in in COnfigAccess.Callback()
//
// Jump to 2)CPU Configuration Form