PcAtChipsetPkg: Add VarPolicy to PcAtRealTimeClock variables

Register a variable policy for L"RTCALARM" and L"RTC".
The policy will enforce strict requiremnts for the variable
size and attributes, and will block updates to the variables
unless those requirements are met.

Signed-off-by: Aaron Pop <aaronpop@microsoft.com>
This commit is contained in:
Mike Turner 2024-07-17 23:23:38 -07:00 committed by mergify[bot]
parent a6a060f940
commit 708e440ddf
5 changed files with 94 additions and 1 deletions

View file

@ -34,7 +34,8 @@
"AcceptableDependencies": [
"MdePkg/MdePkg.dec",
"PcAtChipsetPkg/PcAtChipsetPkg.dec",
"UefiCpuPkg/UefiCpuPkg.dec"
"UefiCpuPkg/UefiCpuPkg.dec",
"MdeModulePkg/MdeModulePkg.dec"
],
# For host based unit tests
"AcceptableDependencies-HOST_APPLICATION":[],

View file

@ -44,6 +44,7 @@
LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
[Components]
PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf

View file

@ -15,6 +15,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Guid/Acpi.h>
#include <Protocol/RealTimeClock.h>
#include <Protocol/VariablePolicy.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
@ -28,6 +29,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/PcdLib.h>
#include <Library/ReportStatusCodeLib.h>
#include <Library/VariablePolicyHelperLib.h>
typedef struct {
EFI_LOCK RtcLock;

View file

@ -139,6 +139,83 @@ VirtualNotifyEvent (
EfiConvertPointer (0x0, (VOID **)&mRtcTargetRegister);
}
/**
Callback function invoked when the VariablePolicy protocol is installed.
This function registers the RTCALARM and RTC variables with the VariablePolicy protocol
to set strict requirements for the variables.
@param[in] Event The notification event (non-NULL when called as a notification callback).
NULL if called directly during initialization.
@param[in] Context The VariablePolicy protocol pointer. Non-NULL when called directly or
when the protocol is available. NULL on the initial notification if
the protocol is not yet installed, in which case this function returns
without error.
**/
STATIC
VOID
EFIAPI
OnVariablePolicyProtocolNotification (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EDKII_VARIABLE_POLICY_PROTOCOL *VariablePolicy;
EFI_STATUS Status;
Status = gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, NULL, (VOID **)&VariablePolicy);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_VERBOSE, "%a: - Variable Policy not yet available - %r\n", __func__, Status));
return;
}
//
// Register policy for RTCALARM variable:
// - Size must be exactly sizeof(EFI_TIME) bytes (no variable-sized buffers)
// - Must have BS_ACCESS, RT_ACCESS, and NON_VOLATILE attributes (required for runtime use)
// - Cannot have any other attributes (prevents tampering)
//
Status = RegisterBasicVariablePolicy (
VariablePolicy,
&gEfiCallerIdGuid,
L"RTCALARM",
sizeof (EFI_TIME),
sizeof (EFI_TIME),
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
(UINT32) ~(EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE),
VARIABLE_POLICY_TYPE_NO_LOCK
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: - Error setting policy for RTCALARM - %r\n", __func__, Status));
ASSERT_EFI_ERROR (Status);
}
//
// Register policy for RTC variable:
// - Size must be exactly sizeof(UINT32) bytes (no variable-sized buffers)
// - Must have BS_ACCESS, RT_ACCESS, and NON_VOLATILE attributes (required for runtime use)
// - Cannot have any other attributes (prevents tampering)
//
Status = RegisterBasicVariablePolicy (
VariablePolicy,
&gEfiCallerIdGuid,
L"RTC",
sizeof (UINT32),
sizeof (UINT32),
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
(UINT32) ~(EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE),
VARIABLE_POLICY_TYPE_NO_LOCK
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: - Error setting policy for RTC - %r\n", __func__, Status));
ASSERT_EFI_ERROR (Status);
}
gBS->CloseEvent (Event);
return;
}
/**
The user Entry Point for PcRTC module.
@ -161,6 +238,7 @@ InitializePcRtc (
{
EFI_STATUS Status;
EFI_EVENT Event;
VOID *ProtocolRegistration;
EfiInitializeLock (&mModuleGlobal.RtcLock, TPL_CALLBACK);
mModuleGlobal.CenturyRtcAddress = GetCenturyRtcAddress ();
@ -229,5 +307,13 @@ InitializePcRtc (
ASSERT_EFI_ERROR (Status);
}
EfiCreateProtocolNotifyEvent (
&gEdkiiVariablePolicyProtocolGuid,
TPL_CALLBACK,
OnVariablePolicyProtocolNotification,
NULL,
&ProtocolRegistration
);
return Status;
}

View file

@ -34,6 +34,7 @@
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
PcAtChipsetPkg/PcAtChipsetPkg.dec
[LibraryClasses]
@ -49,9 +50,11 @@
BaseLib
PcdLib
ReportStatusCodeLib
VariablePolicyHelperLib
[Protocols]
gEfiRealTimeClockArchProtocolGuid ## PRODUCES
gEdkiiVariablePolicyProtocolGuid ## CONSUMES
[Guids]
## SOMETIMES_CONSUMES ## Event