Security enhancement to SMM Base thunk drivers: Framework SMM drivers can't be loaded after SMRAM is locked.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10316 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@ -32,6 +32,7 @@
|
|||||||
#include <Protocol/SmmCpuSaveState.h>
|
#include <Protocol/SmmCpuSaveState.h>
|
||||||
#include <Protocol/MpService.h>
|
#include <Protocol/MpService.h>
|
||||||
#include <Protocol/LoadPe32Image.h>
|
#include <Protocol/LoadPe32Image.h>
|
||||||
|
#include <Protocol/SmmReadyToLock.h>
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Structure for tracking paired information of registered Framework SMI handler
|
/// Structure for tracking paired information of registered Framework SMI handler
|
||||||
@ -67,6 +68,7 @@ EFI_GUID mEfiSmmCpuIoGuid = EFI_SMM_CPU_IO_GUID;
|
|||||||
EFI_SMM_BASE_HELPER_READY_PROTOCOL *mSmmBaseHelperReady;
|
EFI_SMM_BASE_HELPER_READY_PROTOCOL *mSmmBaseHelperReady;
|
||||||
EFI_SMM_SYSTEM_TABLE *mFrameworkSmst;
|
EFI_SMM_SYSTEM_TABLE *mFrameworkSmst;
|
||||||
UINTN mNumberOfProcessors;
|
UINTN mNumberOfProcessors;
|
||||||
|
BOOLEAN mLocked = FALSE;
|
||||||
|
|
||||||
LIST_ENTRY mCallbackInfoListHead = INITIALIZE_LIST_HEAD_VARIABLE (mCallbackInfoListHead);
|
LIST_ENTRY mCallbackInfoListHead = INITIALIZE_LIST_HEAD_VARIABLE (mCallbackInfoListHead);
|
||||||
|
|
||||||
@ -272,7 +274,7 @@ Register (
|
|||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
if (FunctionData->Args.Register.LegacyIA32Binary) {
|
if (mLocked || FunctionData->Args.Register.LegacyIA32Binary) {
|
||||||
Status = EFI_UNSUPPORTED;
|
Status = EFI_UNSUPPORTED;
|
||||||
} else {
|
} else {
|
||||||
Status = LoadImage (
|
Status = LoadImage (
|
||||||
@ -463,6 +465,11 @@ RegisterCallback (
|
|||||||
{
|
{
|
||||||
CALLBACK_INFO *Buffer;
|
CALLBACK_INFO *Buffer;
|
||||||
|
|
||||||
|
if (mLocked) {
|
||||||
|
FunctionData->Status = EFI_UNSUPPORTED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Note that MakeLast and FloatingPointSave options are not supported in PI SMM
|
/// Note that MakeLast and FloatingPointSave options are not supported in PI SMM
|
||||||
///
|
///
|
||||||
@ -512,11 +519,15 @@ HelperAllocatePool (
|
|||||||
IN OUT SMMBASE_FUNCTION_DATA *FunctionData
|
IN OUT SMMBASE_FUNCTION_DATA *FunctionData
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
FunctionData->Status = gSmst->SmmAllocatePool (
|
if (mLocked) {
|
||||||
FunctionData->Args.AllocatePool.PoolType,
|
FunctionData->Status = EFI_UNSUPPORTED;
|
||||||
FunctionData->Args.AllocatePool.Size,
|
} else {
|
||||||
FunctionData->Args.AllocatePool.Buffer
|
FunctionData->Status = gSmst->SmmAllocatePool (
|
||||||
);
|
FunctionData->Args.AllocatePool.PoolType,
|
||||||
|
FunctionData->Args.AllocatePool.Size,
|
||||||
|
FunctionData->Args.AllocatePool.Buffer
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -529,8 +540,12 @@ HelperFreePool (
|
|||||||
IN OUT SMMBASE_FUNCTION_DATA *FunctionData
|
IN OUT SMMBASE_FUNCTION_DATA *FunctionData
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
FreePool (FunctionData->Args.FreePool.Buffer);
|
if (mLocked) {
|
||||||
FunctionData->Status = EFI_SUCCESS;
|
FunctionData->Status = EFI_UNSUPPORTED;
|
||||||
|
} else {
|
||||||
|
FreePool (FunctionData->Args.FreePool.Buffer);
|
||||||
|
FunctionData->Status = EFI_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -633,6 +648,29 @@ SmmHandlerEntry (
|
|||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Smm Ready To Lock event notification handler.
|
||||||
|
|
||||||
|
It sets a flag indicating that SMRAM has been locked.
|
||||||
|
|
||||||
|
@param[in] Protocol Points to the protocol's unique identifier.
|
||||||
|
@param[in] Interface Points to the interface instance.
|
||||||
|
@param[in] Handle The handle on which the interface was installed.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Notification handler runs successfully.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
SmmReadyToLockEventNotify (
|
||||||
|
IN CONST EFI_GUID *Protocol,
|
||||||
|
IN VOID *Interface,
|
||||||
|
IN EFI_HANDLE Handle
|
||||||
|
)
|
||||||
|
{
|
||||||
|
mLocked = TRUE;
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Entry point function of the SMM Base Helper SMM driver.
|
Entry point function of the SMM Base Helper SMM driver.
|
||||||
|
|
||||||
@ -653,6 +691,7 @@ SmmBaseHelperMain (
|
|||||||
EFI_MP_SERVICES_PROTOCOL *MpServices;
|
EFI_MP_SERVICES_PROTOCOL *MpServices;
|
||||||
EFI_HANDLE Handle;
|
EFI_HANDLE Handle;
|
||||||
UINTN NumberOfEnabledProcessors;
|
UINTN NumberOfEnabledProcessors;
|
||||||
|
VOID *Registration;
|
||||||
|
|
||||||
Handle = NULL;
|
Handle = NULL;
|
||||||
///
|
///
|
||||||
@ -697,6 +736,16 @@ SmmBaseHelperMain (
|
|||||||
mSmmBaseHelperReady->FrameworkSmst = mFrameworkSmst;
|
mSmmBaseHelperReady->FrameworkSmst = mFrameworkSmst;
|
||||||
mSmmBaseHelperReady->ServiceEntry = SmmHandlerEntry;
|
mSmmBaseHelperReady->ServiceEntry = SmmHandlerEntry;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Register SMM Ready To Lock Protocol notification
|
||||||
|
//
|
||||||
|
Status = gSmst->SmmRegisterProtocolNotify (
|
||||||
|
&gEfiSmmReadyToLockProtocolGuid,
|
||||||
|
SmmReadyToLockEventNotify,
|
||||||
|
&Registration
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Register SMM Base Helper services for SMM Base Thunk driver
|
/// Register SMM Base Helper services for SMM Base Thunk driver
|
||||||
///
|
///
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
gEfiMpServiceProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
gEfiMpServiceProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||||
gEfiSmmCpuIo2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
gEfiSmmCpuIo2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||||
gEfiLoadPeImageProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
gEfiLoadPeImageProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||||
|
gEfiSmmReadyToLockProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||||
|
|
||||||
[Depex]
|
[Depex]
|
||||||
gEfiSmmCpuProtocolGuid AND
|
gEfiSmmCpuProtocolGuid AND
|
||||||
|
@ -44,6 +44,7 @@ EFI_HANDLE mSmmBaseHandle = NULL;
|
|||||||
EFI_SMM_BASE2_PROTOCOL *mSmmBase2 = NULL;
|
EFI_SMM_BASE2_PROTOCOL *mSmmBase2 = NULL;
|
||||||
EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL;
|
EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL;
|
||||||
EFI_SMM_BASE_HELPER_READY_PROTOCOL *mSmmBaseHelperReady = NULL;
|
EFI_SMM_BASE_HELPER_READY_PROTOCOL *mSmmBaseHelperReady = NULL;
|
||||||
|
BOOLEAN mAtRuntime = FALSE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Determine if in SMM mode.
|
Determine if in SMM mode.
|
||||||
@ -133,7 +134,7 @@ SmmBaseRegister (
|
|||||||
IN BOOLEAN LegacyIA32Binary
|
IN BOOLEAN LegacyIA32Binary
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (LegacyIA32Binary) {
|
if (mAtRuntime || LegacyIA32Binary) {
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,6 +167,10 @@ SmmBaseUnregister (
|
|||||||
IN EFI_HANDLE ImageHandle
|
IN EFI_HANDLE ImageHandle
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
if (mAtRuntime) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
mCommunicationData.FunctionData.Function = SmmBaseFunctionUnregister;
|
mCommunicationData.FunctionData.Function = SmmBaseFunctionUnregister;
|
||||||
mCommunicationData.FunctionData.Args.UnRegister.ImageHandle = ImageHandle;
|
mCommunicationData.FunctionData.Args.UnRegister.ImageHandle = ImageHandle;
|
||||||
|
|
||||||
@ -308,6 +313,10 @@ SmmBaseSmmAllocatePool (
|
|||||||
OUT VOID **Buffer
|
OUT VOID **Buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
if (mAtRuntime) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
mCommunicationData.FunctionData.Function = SmmBaseFunctionAllocatePool;
|
mCommunicationData.FunctionData.Function = SmmBaseFunctionAllocatePool;
|
||||||
mCommunicationData.FunctionData.Args.AllocatePool.PoolType = PoolType;
|
mCommunicationData.FunctionData.Args.AllocatePool.PoolType = PoolType;
|
||||||
mCommunicationData.FunctionData.Args.AllocatePool.Size = Size;
|
mCommunicationData.FunctionData.Args.AllocatePool.Size = Size;
|
||||||
@ -336,6 +345,10 @@ SmmBaseSmmFreePool (
|
|||||||
IN VOID *Buffer
|
IN VOID *Buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
if (mAtRuntime) {
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
mCommunicationData.FunctionData.Function = SmmBaseFunctionFreePool;
|
mCommunicationData.FunctionData.Function = SmmBaseFunctionFreePool;
|
||||||
mCommunicationData.FunctionData.Args.FreePool.Buffer = Buffer;
|
mCommunicationData.FunctionData.Args.FreePool.Buffer = Buffer;
|
||||||
|
|
||||||
@ -408,6 +421,24 @@ EFI_SMM_BASE_PROTOCOL mSmmBase = {
|
|||||||
SmmBaseGetSmstLocation
|
SmmBaseGetSmstLocation
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Notification function on Exit Boot Services Event.
|
||||||
|
|
||||||
|
This function sets a flag indicating it is in Runtime phase.
|
||||||
|
|
||||||
|
@param Event Event whose notification function is being invoked
|
||||||
|
@param Context Pointer to the notification function's context
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
SmmBaseExitBootServicesEventNotify (
|
||||||
|
IN EFI_EVENT Event,
|
||||||
|
IN VOID *Context
|
||||||
|
)
|
||||||
|
{
|
||||||
|
mAtRuntime = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Entry Point for SMM Base Protocol on SMM Base2 Protocol Thunk driver.
|
Entry Point for SMM Base Protocol on SMM Base2 Protocol Thunk driver.
|
||||||
|
|
||||||
@ -449,6 +480,19 @@ SmmBaseThunkMain (
|
|||||||
Status = gBS->LocateProtocol (&gEfiSmmBaseHelperReadyProtocolGuid, NULL, (VOID **) &mSmmBaseHelperReady);
|
Status = gBS->LocateProtocol (&gEfiSmmBaseHelperReadyProtocolGuid, NULL, (VOID **) &mSmmBaseHelperReady);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create event notification on Exit Boot Services event.
|
||||||
|
//
|
||||||
|
Status = gBS->CreateEventEx (
|
||||||
|
EVT_NOTIFY_SIGNAL,
|
||||||
|
TPL_NOTIFY,
|
||||||
|
SmmBaseExitBootServicesEventNotify,
|
||||||
|
NULL,
|
||||||
|
&gEfiEventExitBootServicesGuid,
|
||||||
|
&Event
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create event on SetVirtualAddressMap() to convert mSmmCommunication from a physical address to a virtual address
|
// Create event on SetVirtualAddressMap() to convert mSmmCommunication from a physical address to a virtual address
|
||||||
//
|
//
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gEfiEventVirtualAddressChangeGuid # GUID ALWAYS_CONSUMED
|
gEfiEventVirtualAddressChangeGuid # GUID ALWAYS_CONSUMED
|
||||||
|
gEfiEventExitBootServicesGuid # GUID ALWAYS_CONSUMED
|
||||||
|
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEfiSmmBase2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
gEfiSmmBase2ProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||||
|
Reference in New Issue
Block a user