summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMario Bălănică <mariobalanica02@gmail.com>2024-06-30 15:59:32 +0300
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-07-16 12:54:07 +0300
commitf9c373c8388f819166e57365197bc423d56209a6 (patch)
tree101d1d4f25f78d73b162b851f8508d94bb9789ef
parent1bb9f47739ae7993191a36bea76c5a2157fdd10f (diff)
downloadedk2-f9c373c8388f819166e57365197bc423d56209a6.tar.xz
EmbeddedPkg: Add option to disable EFI Memory Attribute Protocol
Introduce a driver that allows users to disable the EFI Memory Attribute protocol through an HII setup option, in order to work around a broken version of rhboot's shim used in some distros (e.g. CentOS Stream 9) which incorrectly invokes the protocol and results in a Synchronous Exception. Default is enabled, which can also be overridden at build time by changing `gEmbeddedTokenSpaceGuid.PcdMemoryAttributeEnabledDefault`. It is only applicable to ARM64 and there isn't any other technical reason for disabling this security feature. See: - https://github.com/microsoft/mu_silicon_arm_tiano/issues/124 - https://edk2.groups.io/g/devel/topic/99631663 - https://github.com/tianocore/edk2/pull/5840 Signed-off-by: Mario Bălănică <mariobalanica02@gmail.com>
-rw-r--r--EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c197
-rw-r--r--EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h22
-rw-r--r--EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf62
-rw-r--r--EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni17
-rw-r--r--EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr35
-rw-r--r--EmbeddedPkg/EmbeddedPkg.dec8
-rw-r--r--EmbeddedPkg/EmbeddedPkg.dsc2
-rw-r--r--EmbeddedPkg/Include/Guid/MemoryAttributeManagerFormSet.h17
8 files changed, 360 insertions, 0 deletions
diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c
new file mode 100644
index 0000000000..7a0156ddbf
--- /dev/null
+++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.c
@@ -0,0 +1,197 @@
+/** @file
+
+ Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include "MemoryAttributeManagerDxe.h"
+
+extern UINT8 MemoryAttributeManagerDxeHiiBin[];
+extern UINT8 MemoryAttributeManagerDxeStrings[];
+
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+STATIC HII_VENDOR_DEVICE_PATH mVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8)(END_DEVICE_PATH_LENGTH),
+ (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+/**
+ Installs HII page for user configuration.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+InstallHiiPages (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+ EFI_HANDLE DriverHandle;
+
+ DriverHandle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mVendorDevicePath,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ HiiHandle = HiiAddPackages (
+ &gMemoryAttributeManagerFormSetGuid,
+ DriverHandle,
+ MemoryAttributeManagerDxeStrings,
+ MemoryAttributeManagerDxeHiiBin,
+ NULL
+ );
+
+ if (HiiHandle == NULL) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mVendorDevicePath,
+ NULL
+ );
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function uninstalls the EFI_MEMORY_ATTRIBUTE_PROTOCOL
+ from CpuDxe's handle.
+**/
+STATIC
+VOID
+UninstallEfiMemoryAttributeProtocol (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ UINTN Size;
+ VOID *MemoryAttributeProtocol;
+
+ Size = sizeof (Handle);
+ Status = gBS->LocateHandle (
+ ByProtocol,
+ &gEfiMemoryAttributeProtocolGuid,
+ NULL,
+ &Size,
+ &Handle
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT (Status == EFI_NOT_FOUND);
+ return;
+ }
+
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gEfiMemoryAttributeProtocolGuid,
+ &MemoryAttributeProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ Status = gBS->UninstallProtocolInterface (
+ Handle,
+ &gEfiMemoryAttributeProtocolGuid,
+ MemoryAttributeProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "EFI Memory Attribute Protocol disabled due to user/platform preference!\n"
+ ));
+}
+
+/**
+ The entry point for MemoryAttributeManagerDxe driver.
+
+ @param[in] ImageHandle The image handle of the driver.
+ @param[in] SystemTable The system table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+MemoryAttributeManagerInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA Config;
+
+ Config.Enabled = PROTOCOL_ENABLED_DEFAULT;
+
+ Size = sizeof (MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA);
+ Status = gRT->GetVariable (
+ MEMORY_ATTRIBUTE_MANAGER_DATA_VAR_NAME,
+ &gMemoryAttributeManagerFormSetGuid,
+ NULL,
+ &Size,
+ &Config
+ );
+ if (EFI_ERROR (Status)) {
+ Status = gRT->SetVariable (
+ MEMORY_ATTRIBUTE_MANAGER_DATA_VAR_NAME,
+ &gMemoryAttributeManagerFormSetGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ Size,
+ &Config
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ if (!Config.Enabled) {
+ UninstallEfiMemoryAttributeProtocol ();
+ }
+
+ return InstallHiiPages ();
+}
diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h
new file mode 100644
index 0000000000..a027f3e4b6
--- /dev/null
+++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.h
@@ -0,0 +1,22 @@
+/** @file
+
+ Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MEMORY_ATTRIBUTE_MANAGER_DXE_H_
+#define MEMORY_ATTRIBUTE_MANAGER_DXE_H_
+
+#include <Guid/MemoryAttributeManagerFormSet.h>
+
+#define PROTOCOL_ENABLED_DEFAULT FixedPcdGetBool(PcdMemoryAttributeEnabledDefault)
+
+#define MEMORY_ATTRIBUTE_MANAGER_DATA_VAR_NAME L"MemoryAttributeManagerData"
+
+typedef struct {
+ BOOLEAN Enabled;
+} MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA;
+
+#endif // __MEMORY_ATTRIBUTE_MANAGER_DXE_H__
diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf
new file mode 100644
index 0000000000..b55639cd71
--- /dev/null
+++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf
@@ -0,0 +1,62 @@
+## @file
+# EFI Memory Attribute Protocol state manager
+#
+# This driver allows users to disable the EFI Memory Attribute protocol
+# through an HII setup option, in order to work around a broken version
+# of rhboot's shim used in some distros (e.g. CentOS Stream 9) which
+# incorrectly invokes the protocol and results in a Synchronous Exception.
+#
+# It is only applicable to ARM64 and there isn't any other technical
+# reason for disabling this security feature.
+#
+# See:
+# - https://github.com/microsoft/mu_silicon_arm_tiano/issues/124
+# - https://edk2.groups.io/g/devel/topic/99631663
+# - https://github.com/tianocore/edk2/pull/5840
+#
+# Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = MemoryAttributeManagerDxe
+ FILE_GUID = 5319346b-66ad-433a-9a91-f7fc286bc9a1
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = MemoryAttributeManagerInitialize
+
+[Sources]
+ MemoryAttributeManagerDxe.c
+ MemoryAttributeManagerDxe.h
+ MemoryAttributeManagerDxeHii.uni
+ MemoryAttributeManagerDxeHii.vfr
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ DebugLib
+ DevicePathLib
+ HiiLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ UefiDriverEntryPoint
+
+[Guids]
+ gMemoryAttributeManagerFormSetGuid
+
+[Protocols]
+ gEfiMemoryAttributeProtocolGuid
+
+[Pcd]
+ gEmbeddedTokenSpaceGuid.PcdMemoryAttributeEnabledDefault
+
+[Depex]
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid AND
+ gEfiMemoryAttributeProtocolGuid
diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni
new file mode 100644
index 0000000000..8537824b1f
--- /dev/null
+++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.uni
@@ -0,0 +1,17 @@
+/** @file
+
+ Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#langdef en-US "English"
+
+#string STR_NULL_STRING #language en-US ""
+
+#string STR_FORM_SET_TITLE #language en-US "EFI Memory Attribute Protocol"
+#string STR_FORM_SET_TITLE_HELP #language en-US "Configure the state of the EFI Memory Attribute Protocol.\n\n"
+ "Some old OS loader versions (e.g. as found in CentOS Stream 9) do not properly support the protocol and may cause a Synchronous Exception. This security feature can be disabled to work around the issue; otherwise it should be kept enabled."
+
+#string STR_ENABLE_PROTOCOL_PROMPT #language en-US "Enable Protocol"
diff --git a/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr
new file mode 100644
index 0000000000..a303426e3c
--- /dev/null
+++ b/EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxeHii.vfr
@@ -0,0 +1,35 @@
+/** @file
+
+ Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi/UefiMultiPhase.h>
+#include <Guid/HiiPlatformSetupFormset.h>
+
+#include "MemoryAttributeManagerDxe.h"
+
+formset
+ guid = MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID,
+ title = STRING_TOKEN(STR_FORM_SET_TITLE),
+ help = STRING_TOKEN(STR_FORM_SET_TITLE_HELP),
+ classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,
+
+ efivarstore MEMORY_ATTRIBUTE_MANAGER_VARSTORE_DATA,
+ attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ name = MemoryAttributeManagerData,
+ guid = MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID;
+
+ form formid = 1,
+ title = STRING_TOKEN(STR_FORM_SET_TITLE);
+
+ checkbox varid = MemoryAttributeManagerData.Enabled,
+ prompt = STRING_TOKEN(STR_ENABLE_PROTOCOL_PROMPT),
+ help = STRING_TOKEN(STR_NULL_STRING),
+ flags = CHECKBOX_DEFAULT | CHECKBOX_DEFAULT_MFG | RESET_REQUIRED,
+ default = PROTOCOL_ENABLED_DEFAULT,
+ endcheckbox;
+ endform;
+endformset;
diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec
index 5dfbbc2933..3497fa1df7 100644
--- a/EmbeddedPkg/EmbeddedPkg.dec
+++ b/EmbeddedPkg/EmbeddedPkg.dec
@@ -73,6 +73,9 @@
## Include/Guid/NvVarStoreFormatted.h
gEdkiiNvVarStoreFormattedGuid = { 0xd1a86e3f, 0x0707, 0x4c35, { 0x83, 0xcd, 0xdc, 0x2c, 0x29, 0xc8, 0x91, 0xa3 } }
+ # Include/Guid/MemoryAttributeManagerFormSet.h
+ gMemoryAttributeManagerFormSetGuid = { 0xefab3427, 0x4793, 0x4e9e, { 0xaa, 0x29, 0x88, 0x0c, 0x9a, 0x77, 0x5b, 0x5f } }
+
[Protocols.common]
gHardwareInterruptProtocolGuid = { 0x2890B3EA, 0x053D, 0x1643, { 0xAD, 0x0C, 0xD6, 0x48, 0x08, 0xDA, 0x3F, 0xF1 } }
gHardwareInterrupt2ProtocolGuid = { 0x32898322, 0x2da1, 0x474a, { 0xba, 0xaa, 0xf3, 0xf7, 0xcf, 0x56, 0x94, 0x70 } }
@@ -192,3 +195,8 @@
# Expected Overflow Android Kernel Command Line Characters
#
gEmbeddedTokenSpaceGuid.PcdAndroidKernelCommandLineOverflow|0|UINT32|0x000005C
+
+ #
+ # EFI Memory Attribute Protocol default enable state
+ #
+ gEmbeddedTokenSpaceGuid.PcdMemoryAttributeEnabledDefault|TRUE|BOOLEAN|0x00000060
diff --git a/EmbeddedPkg/EmbeddedPkg.dsc b/EmbeddedPkg/EmbeddedPkg.dsc
index e9062cacbb..ef66aea29d 100644
--- a/EmbeddedPkg/EmbeddedPkg.dsc
+++ b/EmbeddedPkg/EmbeddedPkg.dsc
@@ -239,6 +239,8 @@
EmbeddedPkg/Drivers/DtPlatformDxe/DtPlatformDxe.inf
EmbeddedPkg/Drivers/FdtClientDxe/FdtClientDxe.inf
+ EmbeddedPkg/Drivers/MemoryAttributeManagerDxe/MemoryAttributeManagerDxe.inf
+
EmbeddedPkg/Drivers/NonCoherentIoMmuDxe/NonCoherentIoMmuDxe.inf {
<LibraryClasses>
DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf
diff --git a/EmbeddedPkg/Include/Guid/MemoryAttributeManagerFormSet.h b/EmbeddedPkg/Include/Guid/MemoryAttributeManagerFormSet.h
new file mode 100644
index 0000000000..2efdf03216
--- /dev/null
+++ b/EmbeddedPkg/Include/Guid/MemoryAttributeManagerFormSet.h
@@ -0,0 +1,17 @@
+/** @file
+
+ Copyright (c) 2023-2024, Mario Bălănică <mariobalanica02@gmail.com>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MEMORY_ATTRIBUTE_MANAGER_FORMSET_H_
+#define MEMORY_ATTRIBUTE_MANAGER_FORMSET_H_
+
+#define MEMORY_ATTRIBUTE_MANAGER_FORMSET_GUID \
+ { 0xefab3427, 0x4793, 0x4e9e, { 0xaa, 0x29, 0x88, 0x0c, 0x9a, 0x77, 0x5b, 0x5f } }
+
+extern EFI_GUID gMemoryAttributeManagerFormSetGuid;
+
+#endif // __MEMORY_ATTRIBUTE_MANAGER_FORMSET_H__