Skip to content
This repository has been archived by the owner on May 17, 2020. It is now read-only.

Commit

Permalink
FwRuntimeServices: Rework to support read-only NVRAM
Browse files Browse the repository at this point in the history
  • Loading branch information
vit9696 committed Aug 7, 2019
1 parent 127e6ab commit 3d2deac
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 129 deletions.
13 changes: 7 additions & 6 deletions Application/CleanNvram/CleanNvram.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ UefiMain (
{
EFI_STATUS Status;
OC_FIRMWARE_RUNTIME_PROTOCOL *FwRuntime;
BOOLEAN Redirect;
OC_FWRT_CONFIG Config;

Print (L"NVRAM cleanup %s\n", APPLE_SUPPORT_VERSION);

Expand All @@ -220,18 +220,19 @@ UefiMain (
);

if (!EFI_ERROR (Status) && FwRuntime->Revision >= OC_FIRMWARE_RUNTIME_REVISION) {
Redirect = FwRuntime->SetNvram (FALSE);
Print (L"Found AMF NVRAM, full access %d\n", Redirect);
ZeroMem (&Config, sizeof (Config));
FwRuntime->SetOverride (&Config);
Print (L"Found AMF NVRAM, full access %d\n", Config.BootVariableRedirect);
} else {
Redirect = FALSE;
FwRuntime = NULL;
Print (L"Missing AMF NVRAM\n");
}

DeleteVariables ();

if (Redirect) {
if (FwRuntime != NULL) {
Print (L"Restoring AMF NVRAM...\n");
FwRuntime->SetNvram (TRUE);
FwRuntime->SetOverride (NULL);
}

Print (L"NVRAM cleanup completed, please reboot!\n");
Expand Down
94 changes: 35 additions & 59 deletions Platform/FwRuntimeServices/FwRuntimeServices.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "FwRuntimeServicesPrivate.h"

#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/OcBootManagementLib.h>
#include <Library/UefiBootServicesTableLib.h>
Expand All @@ -22,73 +23,49 @@
#include <Protocol/LoadedImage.h>
#include <Protocol/OcFirmwareRuntime.h>

STATIC EFI_IMAGE_START mStoredStartImage;

STATIC UINTN mNestedCount;

EFI_STATUS
STATIC
VOID
EFIAPI
WrapStartImage (
IN EFI_HANDLE ImageHandle,
OUT UINTN *ExitDataSize,
OUT CHAR16 **ExitData OPTIONAL
FwGetCurrent (
OUT OC_FWRT_CONFIG *Config
)
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *AppleLoadedImage;

AppleLoadedImage = OcGetAppleBootLoadedImage (ImageHandle);

//
// Nest count checking is used to protect from situations like
// Start BootLoader → { Start App, App Finished, Start Kernel }
//
++mNestedCount;
CopyMem (Config, gCurrentConfig, sizeof (*Config));
}

if (mNestedCount == 1) {
//
// Request boot variable redirection if enabled.
//
SetBootVariableRedirect (TRUE);

if (AppleLoadedImage) {
//
// Latest Windows brings Virtualization-based security and monitors
// CR0 by launching itself under a hypevisor. Since we need WP disable
// on macOS to let NVRAM work, and for the time being no other OS
// requires it, here we decide to use it for macOS exclusively.
//
SetWriteUnprotectorMode (TRUE);
}

Status = mStoredStartImage (ImageHandle, ExitDataSize, ExitData);

if (AppleLoadedImage) {
//
// We failed but other operating systems should be loadable.
//
SetWriteUnprotectorMode (FALSE);
}
STATIC
VOID
EFIAPI
FwSetMain (
IN CONST OC_FWRT_CONFIG *Config
)
{
CopyMem (&gMainConfig, Config, sizeof (gMainConfig));
}

//
// Disable redirect on failure, this is cleaner design-wise.
//
SetBootVariableRedirect (FALSE);
STATIC
VOID
EFIAPI
FwSetOverride (
IN CONST OC_FWRT_CONFIG *Config
)
{
if (Config != NULL) {
CopyMem (&gOverrideConfig, Config, sizeof (gOverrideConfig));
gCurrentConfig = &gOverrideConfig;
} else {
Status = mStoredStartImage (ImageHandle, ExitDataSize, ExitData);
gCurrentConfig = &gMainConfig;
}

--mNestedCount;

return Status;
}

STATIC
OC_FIRMWARE_RUNTIME_PROTOCOL
mOcFirmwareRuntimeProtocol = {
OC_FIRMWARE_RUNTIME_REVISION,
SetBootVariableRedirect,
SetCustomGetVariableHandler
FwGetCurrent,
FwSetMain,
FwSetOverride,
FwOnGetVariable
};

EFI_STATUS
Expand All @@ -115,11 +92,10 @@ UefiEntrypoint (
return EFI_ALREADY_STARTED;
}

mStoredStartImage = gBS->StartImage;
gBS->StartImage = WrapStartImage;

gBS->Hdr.CRC32 = 0;
gBS->CalculateCrc32 (gBS, gBS->Hdr.HeaderSize, &gBS->Hdr.CRC32);
//
// Activate main configuration.
//
gCurrentConfig = &gMainConfig;

RedirectRuntimeServices ();

Expand Down
1 change: 0 additions & 1 deletion Platform/FwRuntimeServices/FwRuntimeServices.inf
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
gAppleBootVariableGuid ## SOMETIMES_CONSUMES

[Protocols]
gEfiLoadedImageProtocolGuid ## CONSUMES
gOcFirmwareRuntimeProtocolGuid ## SOMETIMES_PRODUCES

[Depex]
Expand Down
29 changes: 17 additions & 12 deletions Platform/FwRuntimeServices/FwRuntimeServicesPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,31 @@
#define FIRMWARE_RUNTIME_SERVICES_PRIVATE_H

#include <Uefi.h>
#include <Protocol/OcFirmwareRuntime.h>

/**
Main runtime services configuration.
**/
extern OC_FWRT_CONFIG gMainConfig;

/**
Override runtime services configuration.
**/
extern OC_FWRT_CONFIG gOverrideConfig;

/**
Current active runtime services configuration (main or override).
**/
extern OC_FWRT_CONFIG *gCurrentConfig;

VOID
RedirectRuntimeServices (
VOID
);

VOID
SetWriteUnprotectorMode (
IN BOOLEAN Enable
);

BOOLEAN
EFIAPI
SetBootVariableRedirect (
IN BOOLEAN Enable
);

EFI_STATUS
EFIAPI
SetCustomGetVariableHandler (
FwOnGetVariable (
IN EFI_GET_VARIABLE GetVariable,
OUT EFI_GET_VARIABLE *OrgGetVariable OPTIONAL
);
Expand Down
74 changes: 23 additions & 51 deletions Platform/FwRuntimeServices/UefiRuntimeServices.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@ STATIC EFI_SET_VARIABLE mStoredSetVariable;
STATIC EFI_GET_NEXT_HIGH_MONO_COUNT mStoredGetNextHighMonotonicCount;
STATIC EFI_RESET_SYSTEM mStoredResetSystem;

STATIC BOOLEAN mBootVariableRedirect;
STATIC BOOLEAN mWriteUnprotector;
STATIC BOOLEAN mRestrictedPermissions;
/**
Configurations to use.
**/
OC_FWRT_CONFIG gMainConfig;
OC_FWRT_CONFIG gOverrideConfig;
OC_FWRT_CONFIG *gCurrentConfig;

/**
Boot phase accessible variables.
Expand All @@ -56,7 +59,7 @@ WriteUnprotectorPrologue (
{
IA32_CR0 Cr0;

if (mWriteUnprotector) {
if (gCurrentConfig->WriteUnprotector) {
*Ints = SaveAndDisableInterrupts ();
Cr0.UintN = AsmReadCr0 ();
if (Cr0.Bits.WP == 1) {
Expand All @@ -81,7 +84,7 @@ WriteUnprotectorEpilogue (
{
IA32_CR0 Cr0;

if (mWriteUnprotector) {
if (gCurrentConfig->WriteUnprotector) {
if (Wp) {
Cr0.UintN = AsmReadCr0 ();
Cr0.Bits.WP = 1;
Expand Down Expand Up @@ -268,15 +271,15 @@ WrapGetVariable (
//
// Abort access to write-only variables.
//
if (mRestrictedPermissions
if (gCurrentConfig->RestrictedVariables
&& CompareGuid (VendorGuid, &gOcWriteOnlyVariableGuid)) {
return EFI_SECURITY_VIOLATION;
}

//
// Redirect Boot-prefixed variables to our own GUID.
//
if (mBootVariableRedirect && IsEfiBootVar (VariableName, VendorGuid)) {
if (gCurrentConfig->BootVariableRedirect && IsEfiBootVar (VariableName, VendorGuid)) {
VendorGuid = &gOcVendorVariableGuid;
Routed = TRUE;
} else {
Expand Down Expand Up @@ -348,7 +351,7 @@ WrapGetNextVariableName (
//
// In case we do not redirect, simply do nothing.
//
if (!mBootVariableRedirect) {
if (!gCurrentConfig->BootVariableRedirect) {
Status = mStoredGetNextVariableName (VariableNameSize, VariableName, VendorGuid);
WriteUnprotectorEpilogue (Ints, Wp);
return Status;
Expand Down Expand Up @@ -518,18 +521,25 @@ WrapSetVariable (
BOOLEAN Ints;
BOOLEAN Wp;

//
// Abort access when running with read-only NVRAM.
//
if (gCurrentConfig->WriteProtection) {
return EFI_SECURITY_VIOLATION;
}

//
// Abort access to read-only variables.
//
if (mRestrictedPermissions
if (gCurrentConfig->RestrictedVariables
&& CompareGuid (VendorGuid, &gOcReadOnlyVariableGuid)) {
return EFI_SECURITY_VIOLATION;
}

//
// Redirect Boot-prefixed variables to our own GUID.
//
if (mBootVariableRedirect && IsEfiBootVar (VariableName, VendorGuid)) {
if (gCurrentConfig->BootVariableRedirect && IsEfiBootVar (VariableName, VendorGuid)) {
VendorGuid = &gOcVendorVariableGuid;
}

Expand Down Expand Up @@ -595,47 +605,9 @@ WrapResetSystem (
WriteUnprotectorEpilogue (Ints, Wp);
}

VOID
SetWriteUnprotectorMode (
IN BOOLEAN Enable
)
{
mWriteUnprotector = Enable;
}

BOOLEAN
EFIAPI
SetBootVariableRedirect (
IN BOOLEAN Enable
)
{
UINTN DataSize;
EFI_STATUS Status;
BOOLEAN Previous;

if (Enable) {
DataSize = sizeof (Enable);
Status = mStoredGetVariable (
OC_BOOT_REDIRECT_VARIABLE_NAME,
&gOcVendorVariableGuid,
NULL,
&DataSize,
&Enable
);

if (EFI_ERROR (Status)) {
Enable = FALSE;
}
}

Previous = mBootVariableRedirect;
mBootVariableRedirect = Enable;
return Previous;
}

EFI_STATUS
EFIAPI
SetCustomGetVariableHandler (
FwOnGetVariable (
IN EFI_GET_VARIABLE GetVariable,
OUT EFI_GET_VARIABLE *OrgGetVariable OPTIONAL
)
Expand Down Expand Up @@ -671,8 +643,8 @@ TranslateAddressesHandler (
gRT->ConvertPointer (0, (VOID **) &mStoredGetNextHighMonotonicCount);
gRT->ConvertPointer (0, (VOID **) &mStoredResetSystem);

mCustomGetVariable = NULL;
mRestrictedPermissions = TRUE;
gRT->ConvertPointer (0, (VOID **) &gCurrentConfig);
mCustomGetVariable = NULL;
}

VOID
Expand Down

0 comments on commit 3d2deac

Please sign in to comment.