From: Evgeniy Baskov <baskov@ispras.ru>
To: Ard Biesheuvel <ardb@kernel.org>
Cc: Evgeniy Baskov <baskov@ispras.ru>, Borislav Petkov <bp@alien8.de>,
Andy Lutomirski <luto@kernel.org>,
Dave Hansen <dave.hansen@linux.intel.com>,
Ingo Molnar <mingo@redhat.com>,
Peter Zijlstra <peterz@infradead.org>,
Thomas Gleixner <tglx@linutronix.de>,
Alexey Khoroshilov <khoroshilov@ispras.ru>,
lvc-project@linuxtesting.org, x86@kernel.org,
linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-hardening@vger.kernel.org
Subject: [PATCH 09/16] efi/libstub: Move helper function to related file
Date: Tue, 6 Sep 2022 13:41:13 +0300 [thread overview]
Message-ID: <a1c01892bad6e4f05da96380b63ff14a82842d27.1662459668.git.baskov@ispras.ru> (raw)
In-Reply-To: <cover.1662459668.git.baskov@ispras.ru>
efi_adjust_memory_range_protection() can be useful outside x86-stub.c.
Move it to mem.c, where memory related code resides and make it
non-static.
Change its behavior to setup exact attibutes and disallow making memory
regions readable and writable simultaniosly for supported
configurations.
Signed-off-by: Evgeniy Baskov <baskov@ispras.ru>
---
drivers/firmware/efi/libstub/efistub.h | 4 +
drivers/firmware/efi/libstub/mem.c | 101 ++++++++++++++++++++++++
drivers/firmware/efi/libstub/x86-stub.c | 67 ++--------------
3 files changed, 111 insertions(+), 61 deletions(-)
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index b0ae0a454404..22fe28385db7 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -907,6 +907,10 @@ efi_status_t efi_relocate_kernel(unsigned long *image_addr,
unsigned long alignment,
unsigned long min_addr);
+efi_status_t efi_adjust_memory_range_protection(unsigned long start,
+ unsigned long size,
+ unsigned long attributes);
+
efi_status_t efi_parse_options(char const *cmdline);
void efi_parse_option_graphics(char *option);
diff --git a/drivers/firmware/efi/libstub/mem.c b/drivers/firmware/efi/libstub/mem.c
index feef8d4be113..89ebc8ad2c22 100644
--- a/drivers/firmware/efi/libstub/mem.c
+++ b/drivers/firmware/efi/libstub/mem.c
@@ -130,3 +130,104 @@ void efi_free(unsigned long size, unsigned long addr)
nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
efi_bs_call(free_pages, addr, nr_pages);
}
+
+/**
+ * efi_adjust_memory_range_protection() - change memory range protection attributes
+ * @start: memory range start address
+ * @size: memory range size
+ *
+ * Actual memory range for which memory attributes are modified is
+ * the smallest ranged with start address and size aligned to EFI_PAGE_SIZE
+ * that includes [start, start + size].
+ *
+ * @return: status code
+ */
+efi_status_t efi_adjust_memory_range_protection(unsigned long start,
+ unsigned long size,
+ unsigned long attributes)
+{
+ efi_status_t status;
+ efi_gcd_memory_space_desc_t desc;
+ efi_physical_addr_t end, next;
+ efi_physical_addr_t rounded_start, rounded_end;
+ efi_physical_addr_t unprotect_start, unprotect_size;
+ int has_system_memory = 0;
+
+ if (efi_dxe_table == NULL)
+ return EFI_UNSUPPORTED;
+
+ /*
+ * This function should not be used to modify attributes
+ * other than writable/executable.
+ */
+
+ if ((attributes & ~(EFI_MEMORY_RO | EFI_MEMORY_XP)) != 0)
+ return EFI_INVALID_PARAMETER;
+
+ /*
+ * Disallow simultaniously executable and writable memory
+ * to inforce W^X policy if direct extraction code is enabled.
+ */
+
+ if ((attributes & (EFI_MEMORY_RO | EFI_MEMORY_XP)) == 0 &&
+ IS_ENABLED(CONFIG_EFI_STUB_EXTRACT_DIRECT))
+ return EFI_INVALID_PARAMETER;
+
+ rounded_start = rounddown(start, EFI_PAGE_SIZE);
+ rounded_end = roundup(start + size, EFI_PAGE_SIZE);
+
+ /*
+ * Don't modify memory region attributes, they are
+ * already suitable, to lower the possibility to
+ * encounter firmware bugs.
+ */
+
+ for (end = start + size; start < end; start = next) {
+
+ status = efi_dxe_call(get_memory_space_descriptor,
+ start, &desc);
+
+ if (status != EFI_SUCCESS) {
+ efi_warn("Unable to get memory descriptor at %lx\n",
+ start);
+ return status;
+ }
+
+ 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 != EfiGcdMemoryTypeSystemMemory) {
+ efi_warn("Attempted to change protection of special memory range\n");
+ return EFI_UNSUPPORTED;
+ }
+
+ if (((desc.attributes ^ attributes) &
+ (EFI_MEMORY_RO | EFI_MEMORY_XP)) == 0)
+ continue;
+
+ desc.attributes &= ~(EFI_MEMORY_RO | EFI_MEMORY_XP);
+ desc.attributes |= attributes;
+
+ unprotect_start = max(rounded_start, desc.base_address);
+ unprotect_size = min(rounded_end, next) - unprotect_start;
+
+ status = efi_dxe_call(set_memory_space_attributes,
+ unprotect_start, unprotect_size,
+ desc.attributes);
+
+ if (status != EFI_SUCCESS) {
+ efi_warn("Unable to unprotect memory range [%08lx,%08lx]: %lx\n",
+ (unsigned long)unprotect_start,
+ (unsigned long)(unprotect_start + unprotect_size),
+ status);
+ return status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
index 05ae8bcc9d67..678f9c2ccafc 100644
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -212,62 +212,6 @@ static void retrieve_apple_device_properties(struct boot_params *boot_params)
}
}
-static void
-adjust_memory_range_protection(unsigned long start, unsigned long size)
-{
- efi_status_t status;
- efi_gcd_memory_space_desc_t desc;
- unsigned long end, next;
- unsigned long rounded_start, rounded_end;
- unsigned long unprotect_start, unprotect_size;
- int has_system_memory = 0;
-
- if (efi_dxe_table == NULL)
- return;
-
- rounded_start = rounddown(start, EFI_PAGE_SIZE);
- rounded_end = roundup(start + size, EFI_PAGE_SIZE);
-
- /*
- * Don't modify memory region attributes, they are
- * already suitable, to lower the possibility to
- * encounter firmware bugs.
- */
-
- for (end = start + size; start < end; start = next) {
-
- status = efi_dxe_call(get_memory_space_descriptor, start, &desc);
-
- if (status != 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 != EfiGcdMemoryTypeSystemMemory ||
- (desc.attributes & (EFI_MEMORY_RO | EFI_MEMORY_XP)) == 0)
- continue;
-
- unprotect_start = max(rounded_start, (unsigned long)desc.base_address);
- unprotect_size = min(rounded_end, next) - unprotect_start;
-
- status = efi_dxe_call(set_memory_space_attributes,
- unprotect_start, unprotect_size,
- EFI_MEMORY_WB);
-
- if (status != EFI_SUCCESS) {
- efi_warn("Unable to unprotect memory range [%08lx,%08lx]: %lx\n",
- unprotect_start,
- unprotect_start + unprotect_size,
- status);
- }
- }
-}
-
/*
* Trampoline takes 2 pages and can be loaded in first megabyte of memory
* with its end placed between 128k and 640k where BIOS might start.
@@ -291,12 +235,12 @@ setup_memory_protection(unsigned long image_base, unsigned long image_size)
* and relocated kernel image.
*/
- adjust_memory_range_protection(TRAMPOLINE_PLACEMENT_BASE,
- TRAMPOLINE_PLACEMENT_SIZE);
+ efi_adjust_memory_range_protection(TRAMPOLINE_PLACEMENT_BASE,
+ TRAMPOLINE_PLACEMENT_SIZE, 0);
#ifdef CONFIG_64BIT
if (image_base != (unsigned long)startup_32)
- adjust_memory_range_protection(image_base, image_size);
+ efi_adjust_memory_range_protection(image_base, image_size, 0);
#else
/*
* Clear protection flags on a whole range of possible
@@ -306,8 +250,9 @@ setup_memory_protection(unsigned long image_base, unsigned long image_size)
* need to remove possible protection on relocated image
* itself disregarding further relocations.
*/
- adjust_memory_range_protection(LOAD_PHYSICAL_ADDR,
- KERNEL_IMAGE_SIZE - LOAD_PHYSICAL_ADDR);
+ efi_adjust_memory_range_protection(LOAD_PHYSICAL_ADDR,
+ KERNEL_IMAGE_SIZE - LOAD_PHYSICAL_ADDR,
+ 0);
#endif
}
--
2.35.1
next prev parent reply other threads:[~2022-09-06 10:42 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-06 10:41 [PATCH 00/16] x86_64: Improvements at compressed kernel stage Evgeniy Baskov
2022-09-06 10:41 ` [PATCH 01/16] x86/boot: Align vmlinuz sections on page size Evgeniy Baskov
2022-10-19 7:01 ` Ard Biesheuvel
2022-10-20 11:13 ` Evgeniy Baskov
2022-09-06 10:41 ` [PATCH 02/16] x86/build: Remove RWX sections and align on 4KB Evgeniy Baskov
2022-10-19 7:04 ` Ard Biesheuvel
2022-10-20 11:15 ` Evgeniy Baskov
2022-09-06 10:41 ` [PATCH 03/16] x86/boot: Set cr0 to known state in trampoline Evgeniy Baskov
2022-10-19 7:06 ` Ard Biesheuvel
2022-10-20 11:23 ` Evgeniy Baskov
2022-10-19 7:44 ` Andrew Cooper
2022-10-20 13:25 ` Evgeniy Baskov
2022-09-06 10:41 ` [PATCH 04/16] x86/boot: Increase boot page table size Evgeniy Baskov
2022-10-19 7:08 ` Ard Biesheuvel
2022-10-20 11:29 ` Evgeniy Baskov
2022-09-06 10:41 ` [PATCH 05/16] x86/boot: Support 4KB pages for identity mapping Evgeniy Baskov
2022-10-19 7:11 ` Ard Biesheuvel
2022-10-20 11:30 ` Evgeniy Baskov
2022-09-06 10:41 ` [PATCH 06/16] x86/boot: Setup memory protection for bzImage code Evgeniy Baskov
2022-10-19 7:17 ` Ard Biesheuvel
2022-10-20 12:07 ` Evgeniy Baskov
2022-10-19 7:57 ` Andrew Cooper
2022-10-20 13:30 ` Evgeniy Baskov
2022-10-20 16:51 ` Andrew Cooper
2022-09-06 10:41 ` [PATCH 07/16] x86/boot: Map memory explicitly Evgeniy Baskov
2022-09-06 10:41 ` [PATCH 08/16] x86/boot: Remove mapping from page fault handler Evgeniy Baskov
2022-10-19 7:20 ` Ard Biesheuvel
2022-09-06 10:41 ` Evgeniy Baskov [this message]
2022-10-19 7:21 ` [PATCH 09/16] efi/libstub: Move helper function to related file Ard Biesheuvel
2022-09-06 10:41 ` [PATCH 10/16] x86/boot: Make console interface more abstract Evgeniy Baskov
2022-10-19 7:23 ` Ard Biesheuvel
2022-10-20 12:10 ` Evgeniy Baskov
2022-09-06 10:41 ` [PATCH 11/16] x86/boot: Split trampoline and pt init code Evgeniy Baskov
2022-09-06 10:41 ` [PATCH 12/16] x86/boot: Add EFI kernel extraction interface Evgeniy Baskov
2022-10-19 7:27 ` Ard Biesheuvel
2022-10-20 12:14 ` Evgeniy Baskov
2022-09-06 10:41 ` [PATCH 13/16] efi/x86: Support extracting kernel from libstub Evgeniy Baskov
2022-10-19 7:35 ` Ard Biesheuvel
2022-10-20 12:36 ` Evgeniy Baskov
2022-09-06 10:41 ` [PATCH 14/16] x86/build: Make generated PE more spec compliant Evgeniy Baskov
2022-10-19 7:39 ` Ard Biesheuvel
2022-10-20 13:07 ` Evgeniy Baskov
2022-09-06 10:41 ` [PATCH 15/16] efi/libstub: Add memory attribute protocol definitions Evgeniy Baskov
2022-10-19 7:39 ` Ard Biesheuvel
2022-09-06 10:41 ` [PATCH 16/16] efi/libstub: Use memory attribute protocol Evgeniy Baskov
2022-10-18 20:51 ` [PATCH] efi/libstub: make memory protection warnings include newlines Peter Jones
2022-10-19 7:44 ` Ard Biesheuvel
2022-10-19 7:42 ` [PATCH 16/16] efi/libstub: Use memory attribute protocol Ard Biesheuvel
2022-10-20 13:13 ` Evgeniy Baskov
2022-10-18 21:04 ` [PATCH 00/16] x86_64: Improvements at compressed kernel stage Peter Jones
2022-10-20 11:05 ` Evgeniy Baskov
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=a1c01892bad6e4f05da96380b63ff14a82842d27.1662459668.git.baskov@ispras.ru \
--to=baskov@ispras.ru \
--cc=ardb@kernel.org \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=khoroshilov@ispras.ru \
--cc=linux-efi@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=lvc-project@linuxtesting.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).