All of lore.kernel.org
 help / color / mirror / Atom feed
From: Baskov Evgeniy <baskov@ispras.ru>
To: grub-devel@gnu.org
Cc: Baskov Evgeniy <baskov@ispras.ru>
Subject: [PATCH RFC 3/3] efi: explicitly set memory attributes for memory
Date: Thu,  7 Apr 2022 06:32:28 +0300	[thread overview]
Message-ID: <20220407033228.30242-4-baskov@ispras.ru> (raw)
In-Reply-To: <20220407033228.30242-1-baskov@ispras.ru>

UEFI specification does not guarantee that memory
used for trampoline by GRUB would be executable.
Some stricter implementations set NX flag for most
regions.

Explicitly mark memory range where trampoline would
be allocated as writable and executable
using DXE services on x86-efi variations.

Avoid modification if not necessary and only modify
system memory to reduce the possibility to encounter
firmware bugs.

Signed-off-by: Baskov Evgeniy <baskov@ispras.ru>

diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
index d8e411454..f6d1170d1 100644
--- a/grub-core/kern/efi/mm.c
+++ b/grub-core/kern/efi/mm.c
@@ -230,6 +230,71 @@ stop_broadcom (void)
 
 #endif
 
+static void
+unprotect_memory_range (grub_efi_physical_address_t start,
+			 grub_efi_physical_address_t end)
+{
+  static grub_efi_guid_t dxe_guid = GRUB_EFI_DXE_SERVICES_TABLE_GUID;
+  grub_efi_physical_address_t rounded_start, rounded_end, next;
+  grub_efi_physical_address_t unprotect_start, unprotect_end;
+  grub_efi_dxe_services_t *dxe;
+  grub_efi_gcd_memory_space_descriptor_t desc;
+  grub_efi_status_t status;
+
+  dxe = grub_efi_get_config_table (&dxe_guid);
+  if (dxe == NULL || dxe->hdr.signature != GRUB_EFI_DXE_SERVICES_SIGNATURE)
+    return;
+
+  rounded_start = start & ~GRUB_EFI_PAGE_SIZE;
+  rounded_end = (end + GRUB_EFI_PAGE_SIZE - 1) & ~GRUB_EFI_PAGE_SIZE;
+
+  /*
+   * Don't modify memory region attributes, they are
+   * already suitable, to lower the possibility to
+   * encounter firmware bugs.
+   */
+
+  for (; start < end; start = next)
+    {
+      status = efi_call_2 (dxe->get_memory_space_descriptor, start, &desc);
+
+      if (status != GRUB_EFI_SUCCESS)
+        return;
+
+      next = desc.base_address + desc.length;
+
+      /*
+       * Only system memory is suitable for trampoline/kernel image placement,
+       * so only this type of memory needs its attributes to be modified.
+       */
+
+      if (desc.gcd_memory_type != GRUB_EFI_GCD_MEMORY_TYPE_SYSTEM_MEMORY ||
+          (desc.attributes & (GRUB_EFI_MEMORY_RO | GRUB_EFI_MEMORY_XP)) == 0)
+        continue;
+
+      unprotect_start = rounded_start;
+      if (unprotect_start < desc.base_address)
+        unprotect_start = desc.base_address;
+
+      unprotect_end = rounded_end;
+      if (unprotect_end > next)
+        unprotect_end = next;
+
+      status = efi_call_3 (dxe->set_memory_space_attributes,
+			   unprotect_start,
+			   unprotect_end - unprotect_start,
+			   GRUB_EFI_MEMORY_WB);
+
+      if (status != GRUB_EFI_SUCCESS)
+	{
+          grub_printf ("Cannot change memory attributes in range [0x%lX, 0x%lX): 0x%lX\n",
+		       (long)unprotect_start,
+		       (long)unprotect_end,
+		       (long)status);
+	}
+    }
+}
+
 grub_err_t
 grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf,
 			       grub_efi_uintn_t *map_key,
@@ -239,6 +304,8 @@ grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf,
   grub_efi_boot_services_t *b;
   grub_efi_status_t status;
 
+  unprotect_memory_range(0x1000, 0xa0000);
+
 #if defined (__i386__) || defined (__x86_64__)
   const grub_uint16_t apple[] = { 'A', 'p', 'p', 'l', 'e' };
   int is_apple;
-- 
2.35.1



      parent reply	other threads:[~2022-04-07 14:23 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-07  3:32 [PATCH RFC 0/3] EFI memory attributes Baskov Evgeniy
2022-04-07  3:32 ` [PATCH RFC 1/3] efi: provide definitions of DXE services table Baskov Evgeniy
2022-04-11  7:12   ` Paul Menzel
2022-04-14 15:15     ` baskov
2022-04-07  3:32 ` [PATCH RFC 2/3] relocator: allocate trampoline in lower 640k Baskov Evgeniy
2022-04-07  3:32 ` Baskov Evgeniy [this message]

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-all 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=20220407033228.30242-4-baskov@ispras.ru \
    --to=baskov@ispras.ru \
    --cc=grub-devel@gnu.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.