From: "Ard Biesheuvel" <ardb@kernel.org>
To: Ard Biesheuvel <ardb@google.com>
Cc: devel@edk2.groups.io, Laszlo Ersek <lersek@redhat.com>,
Gerd Hoffmann <kraxel@redhat.com>,
Oliver Steffen <osteffen@redhat.com>,
Alexander Graf <graf@amazon.com>,
Oliver Smith-Denny <osde@linux.microsoft.com>,
Taylor Beebe <taylor.d.beebe@gmail.com>,
Peter Jones <pjones@redhat.com>,
Leif Lindholm <quic_llindhol@quicinc.com>
Subject: Re: [edk2-devel] [PATCH v2] ArmVirt: Allow memory attributes protocol to be disabled on first boot
Date: Fri, 8 Dec 2023 12:20:29 +0100 [thread overview]
Message-ID: <CAMj1kXGVTJCAH3j7wXsu8-=iRYWPB-AzDKSmCinwjmJv_DX_mQ@mail.gmail.com> (raw)
In-Reply-To: <20231207100603.2654084-1-ardb@google.com>
On Thu, 7 Dec 2023 at 11:06, Ard Biesheuvel <ardb@google.com> wrote:
>
> From: Ard Biesheuvel <ardb@kernel.org>
>
> Shim's PE loader uses the EFI memory attributes protocol in a way that
> results in an immediate crash when invoking the loaded image, unless the
> base and size of its executable segment are both aligned to 4k.
>
> If this is not the case, it will strip the memory allocation of its
> executable permissions, but fail to add them back for the executable
> region, resulting in non-executable code. Unfortunately, the PE loader
> does not even bother invoking the protocol in this case (as it notices
> the misalignment), making it very hard for system firmware to work
> around this by attempting to infer the intent of the caller.
>
> So let's introduce a QEMU command line option to indicate that the
> protocol should not be exposed at all on the first boot, which is when
> the issue is triggered. (fbaa64.efi is broken but grubaa64.efi boots
> fine)
>
> -fw_cfg opt/org.tianocore/UninstallMemAttrProtocolOnFirstBoot,string=y
>
> Also introduce a fixed boolean PCD that sets the default.
>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Gerd Hoffmann <kraxel@redhat.com>
> Cc: Oliver Steffen <osteffen@redhat.com>
> Cc: Alexander Graf <graf@amazon.com>
> Cc: Oliver Smith-Denny <osde@linux.microsoft.com>
> Cc: Taylor Beebe <taylor.d.beebe@gmail.com>
> Cc: Peter Jones <pjones@redhat.com>
> Cc: Leif Lindholm <quic_llindhol@quicinc.com>
> Link: https://gitlab.com/qemu-project/qemu/-/issues/1990
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
OK, if nobody has problems with this approach, I intend to merge it
and give a snapshot build to the lima folks to incorporate in their
scripts.
> ---
> ArmVirtPkg/ArmVirtPkg.dec | 6 ++
> ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf | 7 ++
> ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBm.c | 85 ++++++++++++++++++++
> 3 files changed, 98 insertions(+)
>
> diff --git a/ArmVirtPkg/ArmVirtPkg.dec b/ArmVirtPkg/ArmVirtPkg.dec
> index 0f2d7873279f..c55978f75c19 100644
> --- a/ArmVirtPkg/ArmVirtPkg.dec
> +++ b/ArmVirtPkg/ArmVirtPkg.dec
> @@ -68,3 +68,9 @@ [PcdsFixedAtBuild, PcdsPatchableInModule]
> # Cloud Hypervisor has no other way to pass Rsdp address to the guest except use a PCD.
>
> #
>
> gArmVirtTokenSpaceGuid.PcdCloudHvAcpiRsdpBaseAddress|0x0|UINT64|0x00000005
>
> +
>
> + ##
>
> + # Whether the EFI memory attribus protocol should be uninstalled before
>
> + # invoking the OS loader on the first boot. This may be needed to work around
>
> + # problematic builds of shim that use the protocol incorrectly.
>
> + gArmVirtTokenSpaceGuid.PcdUninstallMemAttrProtocolOnFirstBoot|FALSE|BOOLEAN|0x00000006
>
> diff --git a/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> index 997eb1a4429f..5d119af6a3b3 100644
> --- a/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> +++ b/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> @@ -16,6 +16,7 @@ [Defines]
> MODULE_TYPE = DXE_DRIVER
>
> VERSION_STRING = 1.0
>
> LIBRARY_CLASS = PlatformBootManagerLib|DXE_DRIVER
>
> + CONSTRUCTOR = PlatformBootManagerLibConstructor
>
>
>
> #
>
> # The following information is for reference only and not required by the build tools.
>
> @@ -46,6 +47,7 @@ [LibraryClasses]
> PcdLib
>
> PlatformBmPrintScLib
>
> QemuBootOrderLib
>
> + QemuFwCfgSimpleParserLib
>
> QemuLoadImageLib
>
> ReportStatusCodeLib
>
> TpmPlatformHierarchyLib
>
> @@ -55,6 +57,7 @@ [LibraryClasses]
> UefiRuntimeServicesTableLib
>
>
>
> [FixedPcd]
>
> + gArmVirtTokenSpaceGuid.PcdUninstallMemAttrProtocolOnFirstBoot
>
> gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
>
> gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
>
> gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
>
> @@ -73,5 +76,9 @@ [Guids]
> [Protocols]
>
> gEfiFirmwareVolume2ProtocolGuid
>
> gEfiGraphicsOutputProtocolGuid
>
> + gEfiMemoryAttributeProtocolGuid
>
> gEfiPciRootBridgeIoProtocolGuid
>
> gVirtioDeviceProtocolGuid
>
> +
>
> +[Depex]
>
> + gEfiVariableArchProtocolGuid
>
> diff --git a/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBm.c b/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBm.c
> index 85c01351b09d..5306d9ea0a05 100644
> --- a/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBm.c
> +++ b/ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBm.c
> @@ -16,6 +16,7 @@
> #include <Library/PcdLib.h>
>
> #include <Library/PlatformBmPrintScLib.h>
>
> #include <Library/QemuBootOrderLib.h>
>
> +#include <Library/QemuFwCfgSimpleParserLib.h>
>
> #include <Library/TpmPlatformHierarchyLib.h>
>
> #include <Library/UefiBootManagerLib.h>
>
> #include <Protocol/DevicePath.h>
>
> @@ -1274,3 +1275,87 @@ PlatformBootManagerUnableToBoot (
> EfiBootManagerBoot (&BootManagerMenu);
>
> }
>
> }
>
> +
>
> +/**
>
> + Uninstall the EFI memory attribute protocol if it exists.
>
> +**/
>
> +STATIC
>
> +VOID
>
> +UninstallEfiMemoryAttributesProtocol (
>
> + 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);
>
> +
>
> + Status = gBS->UninstallProtocolInterface (
>
> + Handle,
>
> + &gEfiMemoryAttributeProtocolGuid,
>
> + MemoryAttributeProtocol
>
> + );
>
> + ASSERT_EFI_ERROR (Status);
>
> +}
>
> +
>
> +EFI_STATUS
>
> +EFIAPI
>
> +PlatformBootManagerLibConstructor (
>
> + IN EFI_HANDLE ImageHandle,
>
> + IN EFI_SYSTEM_TABLE *SystemTable
>
> + )
>
> +{
>
> + BOOLEAN Uninstall;
>
> + UINTN VarSize;
>
> + UINT32 Attr;
>
> +
>
> + //
>
> + // Work around shim's terminally broken use of the EFI memory attributes
>
> + // protocol, by uninstalling it if requested on the QEMU command line.
>
> + //
>
> + // E.g.,
>
> + // -fw_cfg opt/org.tianocore/UninstallMemAttrProtocolOnFirstBoot,string=y
>
> + //
>
> + // This is only needed on the first boot, when fbaa64.efi is being invoked to
>
> + // set the boot order variables. Subsequent boots involving GRUB are not
>
> + // affected.
>
> + //
>
> + VarSize = 0;
>
> + if (gRT->GetVariable (
>
> + L"BootOrder",
>
> + &gEfiGlobalVariableGuid,
>
> + &Attr,
>
> + &VarSize,
>
> + NULL
>
> + ) == EFI_NOT_FOUND)
>
> + {
>
> + Uninstall = FixedPcdGetBool (PcdUninstallMemAttrProtocolOnFirstBoot);
>
> + QemuFwCfgParseBool ("opt/org.tianocore/UninstallMemAttrProtocolOnFirstBoot", &Uninstall);
>
> + if (Uninstall) {
>
> + UninstallEfiMemoryAttributesProtocol ();
>
> + }
>
> + }
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> --
> 2.43.0.rc2.451.g8631bc7472-goog
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#112225): https://edk2.groups.io/g/devel/message/112225
Mute This Topic: https://groups.io/mt/103031504/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2023-12-08 11:20 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-07 10:06 [edk2-devel] [PATCH v2] ArmVirt: Allow memory attributes protocol to be disabled on first boot Ard Biesheuvel
2023-12-08 11:20 ` Ard Biesheuvel [this message]
2023-12-11 0:02 ` Alexander Graf via groups.io
2023-12-08 14:34 ` Laszlo Ersek
2023-12-08 14:49 ` Laszlo Ersek
2023-12-08 15:34 ` Ard Biesheuvel
2023-12-11 14:27 ` Laszlo Ersek
2023-12-11 9:05 ` Gerd Hoffmann
2023-12-11 9:25 ` Ard Biesheuvel
2023-12-11 9:59 ` Gerd Hoffmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAMj1kXGVTJCAH3j7wXsu8-=iRYWPB-AzDKSmCinwjmJv_DX_mQ@mail.gmail.com' \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox