alder_lake_bios/Oem/L05/FeatureCommon/InsydeL05ModulePkg/VariableRuntimeProtectionDxe/VariableRuntimeProtectionDxe.c

318 lines
9.8 KiB
C

/** @file
Variable Runtime Protection by hooking gRT->SetVariable()
;******************************************************************************
;* Copyright (c) 2014, Insyde Software Corporation. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include "VariableRuntimeProtectionDxe.h"
EFI_SET_VARIABLE mOrgRuntimeSetVariable = NULL;
EFI_L05_PROTECTION_VARIABLE_INFO mVariableProtectionList[] = {
{
SYSTEM_CONFIGURATION_GUID, // gSystemConfigurationGuid
SETUP_VARIABLE_NAME
},
//_Start_L05_WIRELESS_DEVICE_SUPPORT_
{
EFI_L05WIRELESS_DEVICE_SUPPORT_VARIABLE_GUID, // gL05WirelessDeviceSupportVariableGuid
L05_WIRELESS_DEVICE_SUPPORT_VARIABLE_NAME_BROADCOM
},
{
EFI_L05WIRELESS_DEVICE_SUPPORT_VARIABLE_GUID, // gL05WirelessDeviceSupportVariableGuid
L05_WIRELESS_DEVICE_SUPPORT_VARIABLE_NAME_INTEL
},
{
EFI_L05WIRELESS_DEVICE_SUPPORT_VARIABLE_GUID, // gL05WirelessDeviceSupportVariableGuid
L05_WIRELESS_DEVICE_SUPPORT_VARIABLE_NAME_QUALCOMM
},
{
EFI_L05WIRELESS_DEVICE_SUPPORT_VARIABLE_GUID, // gL05WirelessDeviceSupportVariableGuid
L05_WIRELESS_DEVICE_SUPPORT_VARIABLE_NAME_REALTEK
},
//_End_L05_WIRELESS_DEVICE_SUPPORT_
{
EFI_GENERIC_VARIABLE_GUID, // gEfiGenericVariableGuid
L"PerfDataMemAddr"
},
};
/**
Hook function for sets the value of a variable.
@param VariableName A Null-terminated string that is the name of the vendor's variable.
Each VariableName is unique for each VendorGuid. VariableName must
contain 1 or more characters. If VariableName is an empty string,
then EFI_INVALID_PARAMETER is returned.
@param VendorGuid A unique identifier for the vendor.
@param Attributes Attributes bitmask to set for the variable.
@param DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE,
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero
causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is
set, then a SetVariable() call with a DataSize of zero will not cause any change to
the variable value (the timestamp associated with the variable may be updated however
even if no new data value is provided,see the description of the
EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not
be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated).
@param Data The contents for the variable.
@retval EFI_SECURITY_VIOLATION Find the matched name and GUID of variable
@retval Others An unexpected error occurred by referring original function gRT->SetVariable()
**/
EFI_STATUS
EFIAPI
SetVariableHookFunc (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN UINT32 Attributes,
IN UINTN DataSize,
IN VOID *Data
)
{
UINT32 Index;
//
// Check name and GUID of variable which need be avoided to modify in Runtime
//
for (Index = 0; Index < sizeof (mVariableProtectionList) / sizeof (EFI_L05_PROTECTION_VARIABLE_INFO); Index++) {
if (StrCmp (VariableName, mVariableProtectionList[Index].VariableName) == 0 &&
CompareGuid (VendorGuid, &(mVariableProtectionList[Index].VariableGuid))) {
return EFI_SECURITY_VIOLATION;
}
}
return mOrgRuntimeSetVariable (VariableName, VendorGuid, Attributes, DataSize, Data);
}
/**
Function for hook gRT->SetVariable()
@param Enabled The setting to determine hook gRT->SetVariable() or not
**/
VOID
HookSetVariable (
BOOLEAN Enabled
)
{
UINT32 Crc32Result;
BOOLEAN ReCalculateCrc32;
Crc32Result = 0;
ReCalculateCrc32 = FALSE;
gRT->Hdr.CRC32 = 0;
if (Enabled) {
//
// Hook gRT->SetVariable()
//
if (mOrgRuntimeSetVariable == NULL) {
mOrgRuntimeSetVariable = gRT->SetVariable;
gRT->SetVariable = SetVariableHookFunc;
ReCalculateCrc32 = TRUE;
}
} else {
//
// Un-hook gRT->SetVariable()
//
if (mOrgRuntimeSetVariable != NULL) {
gRT->SetVariable = mOrgRuntimeSetVariable;
mOrgRuntimeSetVariable = NULL;
ReCalculateCrc32 = TRUE;
}
}
//
// ReCalculate a 32-bit CRC to make sure the contents of the EFI System Table are valid.
//
if (ReCalculateCrc32) {
gBS->CalculateCrc32 ((VOID *) &(gRT->Hdr), gRT->Hdr.HeaderSize, &Crc32Result);
gRT->Hdr.CRC32 = Crc32Result;
}
}
/**
Ready To Boot Envet callback function for enable Variable Runtime Protection
@param Event Pointer to this event
@param Context Event hanlder private data
**/
VOID
EFIAPI
EnableVariableRuntimeProtectionCallBack (
IN EFI_EVENT Event,
IN VOID *Context
)
{
HookSetVariable (TRUE);
return;
}
/**
Return From Image Envet callback function for disable Variable Runtime Protection
@param Event Pointer to this event
@param Context Event hanlder private data
**/
VOID
EFIAPI
DisableVariableRuntimeProtectionCallBack (
IN EFI_EVENT Event,
IN VOID *Context
)
{
HookSetVariable (FALSE);
return;
}
/**
Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
It convers pointer to new virtual address.
@param Event Event whose notification function is being invoked.
@param Context Pointer to the notification function's context.
**/
VOID
EFIAPI
VirtualAddressChangeNotify (
IN EFI_EVENT Event,
IN VOID *Context
)
{
//
// Convert the original function of pointer gRT->SetVariable() if be hooked before
//
if (mOrgRuntimeSetVariable != NULL) {
gRT->ConvertPointer (0x0, (VOID **) &mOrgRuntimeSetVariable);
}
return;
}
/**
This is the declaration of an EFI image entry point. This entry point is
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
both device drivers and bus drivers.
@param ImageHandle The firmware allocated handle for the UEFI image.
@param SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The operation completed successfully.
@retval Others An unexpected error occurred.
**/
EFI_STATUS
EFIAPI
VariableRuntimeProtectionDxeDriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_EVENT ReadyToBootEvent;
EFI_EVENT ReturnFromImageEvent;
VOID *Registration;
EFI_EVENT VirtualAddressChangeEvent;
Status = EFI_SUCCESS;
ReadyToBootEvent = NULL;
ReturnFromImageEvent = NULL;
Registration = NULL;
VirtualAddressChangeEvent = NULL;
//
// Register Ready To Boot Envet for enable Variable Runtime Protection
//
Status = EfiCreateEventReadyToBootEx (
TPL_NOTIFY,
EnableVariableRuntimeProtectionCallBack,
NULL,
&ReadyToBootEvent
);
if (EFI_ERROR (Status)) {
goto Done;
}
//
// Register Return From Image Envet for disable Variable Runtime Protection
//
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
DisableVariableRuntimeProtectionCallBack,
NULL,
&ReturnFromImageEvent
);
if (!EFI_ERROR (Status)) {
Status = gBS->RegisterProtocolNotify (
&gReturnFromImageGuid,
ReturnFromImageEvent,
&Registration
);
if (EFI_ERROR (Status)) {
goto Done;
}
} else {
goto Done;
}
//
// Register the event to convert the pointer for runtime.
//
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
VirtualAddressChangeNotify,
NULL,
&gEfiEventVirtualAddressChangeGuid,
&VirtualAddressChangeEvent
);
if (EFI_ERROR (Status)) {
goto Done;
}
Done:
//
// Close all Events if any error occurred
//
if (EFI_ERROR (Status)) {
if (ReadyToBootEvent != NULL) gBS->CloseEvent (ReadyToBootEvent);
if (ReturnFromImageEvent != NULL) gBS->CloseEvent (ReturnFromImageEvent);
if (VirtualAddressChangeEvent != NULL) gBS->CloseEvent (VirtualAddressChangeEvent);
}
return Status;
}