From: "Ard Biesheuvel" <ardb@kernel.org>
To: devel@edk2.groups.io, osde@linux.microsoft.com
Cc: Leif Lindholm <quic_llindhol@quicinc.com>,
Ard Biesheuvel <ardb+tianocore@kernel.org>,
Sami Mujawar <sami.mujawar@arm.com>,
Michael Kubacki <mikuback@linux.microsoft.com>,
Sean Brogan <sean.brogan@microsoft.com>
Subject: Re: [edk2-devel][PATCH v1 1/1] ArmPkg: CpuDxe: Sync GCD Capabilities With Page Table Attributes
Date: Wed, 7 Jun 2023 19:31:41 +0200 [thread overview]
Message-ID: <CAMj1kXEs71=NsKbjJZTLNkQqMcfiVqPC8vBMBoLiJpVQ5J1Msg@mail.gmail.com> (raw)
In-Reply-To: <f9c91538-49c5-811d-362b-9638013fdc67@linux.microsoft.com>
On Wed, 7 Jun 2023 at 18:10, Oliver Smith-Denny
<osde@linux.microsoft.com> wrote:
>
> Per the discussion in the memory protections design meeting
> this morning, I am kicking this patch back to the top of
> the inbox for review. If folks would like me to resend this
> patchset since the thread got bogged down with scheduling
> meetings, just let me know.
>
> I'll also pull up the BZ link for when the equivalent
> change went into the x86 CpuDxe driver in 2017:
>
> https://bugzilla.tianocore.org/show_bug.cgi?id=753
>
> This contains lots of information about why the change went
> in on the x86 side (some dead mail links, but they can be
> retrieved through some digging). AFAICT, this change wasn't
> applied to ARM at the time due to an oversight, not a general
> design decision.
>
Thanks for the background, this is useful.
So I agree that for all system memory regions, we should be setting
the RP, RO and XP capabilities. But what I don't understand is why
these are not set to begin with.
IOW, the resource descriptor HOBs that the initial regions are based
on should have these capabilities set already, and then, we wouldn't
have to do anything to at this point. If there is anything missing
from the generic plumbing to make sure this transformation happens
correctly, we should fix that first, and fix the existing ARM
platforms to set the correct resource attributes.
For example, ArmVirtQemu uses
ResourceAttributes = (
EFI_RESOURCE_ATTRIBUTE_PRESENT |
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
EFI_RESOURCE_ATTRIBUTE_TESTED
);
for the resource descriptor HOBs, and afaict, this should include
EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE
EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE
EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE
to accurately describe the region's capabilities.
WIth that out of the way, I wonder if we still need this patch at all.
Thanks,
Ard.
>
> On 4/25/2023 5:09 PM, Oliver Smith-Denny wrote:
> > When ArmPkg's CpuDxe driver initializes, it attempts to sync the
> >
> > GCD with the page table. However, unlike when the UefiCpuPkg's
> >
> > CpuDxe initializes, the Arm version does not update the GCD
> >
> > capabilities with EFI_MEMORY_[RO|RP|XP] (this could also set
> >
> > the capabilities to be the existing page table attributes for
> >
> > this range, but the UefiCpuPkg CpuDxe sets the above attributes
> >
> > as they are software constructs, possible to set for any memory
> >
> > hardware).
> >
> >
> >
> > As a result, when the GCD attributes are attempted to be set
> >
> > against the old GCD capabilities, attributes that are set in the
> >
> > page table can get lost because the new attributes are not in the
> >
> > old GCD capabilities (and yet they are already set in the page
> >
> > table) meaning that the attempted sync between the GCD and the
> >
> > page table was a failure and drivers querying one vs the other
> >
> > will see different state. This can lead to RWX memory regions
> >
> > even with the no-execute policy set, because core drivers (such
> >
> > as NonDiscoverablePciDeviceIo, to be fixed up in a later patchset)
> >
> > allocate pages, query the GCD attributes, attempt to set a new
> >
> > cache attribute and end up clearing the XP bit in the page table
> >
> > because the GCD attributes do not have XP set.
> >
> >
> >
> > This patch follows the UefiCpuPkg pattern and adds
> >
> > EFI_MEMORY_[RO|RP|XP] to the GCD capabilities during CpuDxe
> >
> > initialization. This ensures that memory regions which already have
> >
> > these attributes set get them set in the GCD attributes, properly
> >
> > syncing between the GCD and the page table.
> >
> >
> >
> > This mitigates the issue seen, however, additional investigations
> >
> > into setting the GCD attributes earlier and maintaining a better
> >
> > sync between the GCD and the page table are being done.
> >
> >
> >
> > Feedback on this proposal is greatly appreciated, particularly
> >
> > any pitfalls or more architectural solutions to issues seen
> >
> > with syncing the GCD and the page table.
> >
> >
> >
> > PR: https://github.com/tianocore/edk2/pull/4311
> >
> > Personal branch: https://github.com/os-d/edk2/tree/osde/sync_aarch64_gcd_capabilities_v1
> >
> >
> >
> > Cc: Leif Lindholm <quic_llindhol@quicinc.com>
> >
> > Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> >
> > Cc: Sami Mujawar <sami.mujawar@arm.com>
> >
> > Cc: Michael Kubacki <mikuback@linux.microsoft.com>
> >
> > Cc: Sean Brogan <sean.brogan@microsoft.com>
> >
> >
> >
> > Signed-off-by: Oliver Smith-Denny <osde@linux.microsoft.com>
> >
> > ---
> >
> > ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c | 55 +++++++++++++++++---
> >
> > 1 file changed, 49 insertions(+), 6 deletions(-)
> >
> >
> >
> > diff --git a/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c b/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c
> >
> > index 2e73719dce04..3ef0380e084f 100644
> >
> > --- a/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c
> >
> > +++ b/ArmPkg/Drivers/CpuDxe/CpuMmuCommon.c
> >
> > @@ -90,6 +90,7 @@ SetGcdMemorySpaceAttributes (
> >
> > UINTN EndIndex;
> >
> > EFI_PHYSICAL_ADDRESS RegionStart;
> >
> > UINT64 RegionLength;
> >
> > + UINT64 Capabilities;
> >
> >
> >
> > DEBUG ((
> >
> > DEBUG_GCD,
> >
> > @@ -146,14 +147,56 @@ SetGcdMemorySpaceAttributes (
> >
> > RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;
> >
> > }
> >
> >
> >
> > + // Always add RO, RP, and XP as all memory is capable of supporting these types (they are software
> >
> > + // constructs, not hardware features) and they are critical to maintaining a security boundary
> >
> > + Capabilities = MemorySpaceMap[Index].Capabilities | EFI_MEMORY_RO | EFI_MEMORY_RP | EFI_MEMORY_XP;
> >
> > +
> >
> > //
> >
> > - // Set memory attributes according to MTRR attribute and the original attribute of descriptor
> >
> > + // Update GCD capabilities as these may have changed in the page table since the GCD was created
> >
> > + // this follows the same pattern as x86 GCD and Page Table syncing
> >
> > //
> >
> > - gDS->SetMemorySpaceAttributes (
> >
> > - RegionStart,
> >
> > - RegionLength,
> >
> > - (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes)
> >
> > - );
> >
> > + Status = gDS->SetMemorySpaceCapabilities (
> >
> > + RegionStart,
> >
> > + RegionLength,
> >
> > + Capabilities
> >
> > + );
> >
> > +
> >
> > + if (EFI_ERROR (Status)) {
> >
> > + DEBUG ((
> >
> > + DEBUG_ERROR,
> >
> > + "%a - failed to update GCD capabilities: 0x%llx on memory region: 0x%llx length: 0x%llx Status: %r\n",
> >
> > + __func__,
> >
> > + Capabilities,
> >
> > + RegionStart,
> >
> > + RegionLength,
> >
> > + Status
> >
> > + ));
> >
> > + ASSERT_EFI_ERROR (Status);
> >
> > + continue;
> >
> > + }
> >
> > +
> >
> > + //
> >
> > + // Set memory attributes according to the page table attribute and the original attribute of descriptor
> >
> > + //
> >
> > + Status = gDS->SetMemorySpaceAttributes (
> >
> > + RegionStart,
> >
> > + RegionLength,
> >
> > + (MemorySpaceMap[Index].Attributes & ~EFI_MEMORY_CACHETYPE_MASK) | (Attributes & Capabilities)
> >
> > + );
> >
> > +
> >
> > + if (EFI_ERROR (Status)) {
> >
> > + DEBUG ((
> >
> > + DEBUG_ERROR,
> >
> > + "%a - failed to update GCD attributes: 0x%llx on memory region: 0x%llx length: 0x%llx Status: %r\n",
> >
> > + __func__,
> >
> > + Attributes,
> >
> > + RegionStart,
> >
> > + RegionLength,
> >
> > + Status
> >
> > + ));
> >
> > + ASSERT_EFI_ERROR (Status);
> >
> > + continue;
> >
> > + }
> >
> > }
> >
> >
> >
> > return EFI_SUCCESS;
> >
next prev parent reply other threads:[~2023-06-07 17:31 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1759538694580A69.7408@groups.io>
2023-06-07 16:10 ` [edk2-devel][PATCH v1 1/1] ArmPkg: CpuDxe: Sync GCD Capabilities With Page Table Attributes Oliver Smith-Denny
2023-06-07 17:31 ` Ard Biesheuvel [this message]
2023-06-07 18:03 ` Oliver Smith-Denny
[not found] ` <176672827230FBF7.32008@groups.io>
2023-07-07 20:13 ` Oliver Smith-Denny
2023-04-26 0:09 Oliver Smith-Denny
2023-05-01 13:02 ` Ard Biesheuvel
2023-05-01 17:03 ` Oliver Smith-Denny
2023-05-01 17:49 ` [edk2-devel] [PATCH " Michael D Kinney
2023-05-01 17:50 ` Ard Biesheuvel
2023-05-01 17:53 ` Oliver Smith-Denny
2023-05-01 17:59 ` Michael D Kinney
2023-05-09 1:35 ` Ni, Ray
2023-05-09 2:03 ` Oliver Smith-Denny
2023-05-09 2:04 ` Michael D Kinney
2023-05-09 6:59 ` Ard Biesheuvel
2023-05-09 14:59 ` Oliver Smith-Denny
2023-05-10 16:10 ` Taylor Beebe
2023-05-16 2:53 ` Ni, Ray
2023-05-16 17:11 ` Oliver Smith-Denny
2023-05-17 7:14 ` Ni, Ray
2023-06-02 2:24 ` Michael Kubacki
2023-06-02 2:42 ` Ni, Ray
2023-06-02 3:09 ` Michael Kubacki
2023-06-02 9:31 ` Ard Biesheuvel
2023-06-06 2:13 ` Michael Kubacki
2023-06-06 3:00 ` Ni, Ray
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='CAMj1kXEs71=NsKbjJZTLNkQqMcfiVqPC8vBMBoLiJpVQ5J1Msg@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