[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v7 04/10] modules: load module sections at page-aligned addresses
From: |
Mate Kukri |
Subject: |
[PATCH v7 04/10] modules: load module sections at page-aligned addresses |
Date: |
Fri, 4 Oct 2024 15:41:26 +0100 |
Currently we load module sections at whatever alignment gcc+ld happened
to dump into the ELF section header, which is often less then the page
size. Since NX protections are page based, this alignment must be
rounded up to page size on platforms supporting NX protections.
This patch switches EFI platforms to load module sections at 4kB
page-aligned addresses.
It then changes the allocation size computation and the loader code in
grub_dl_load_segments() to align the locations and sizes up to these
boundaries, and fills any added padding with zeros.
All of this happens before relocations are applied, so the relocations
factor that in with no change.
Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
---
grub-core/kern/dl.c | 45 +++++++++++++++++++++++++++++----------------
include/grub/dl.h | 9 +++++++++
2 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
index 37db9fab0..5dc15f070 100644
--- a/grub-core/kern/dl.c
+++ b/grub-core/kern/dl.c
@@ -224,25 +224,34 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
{
unsigned i;
const Elf_Shdr *s;
- grub_size_t tsize = 0, talign = 1;
+ grub_size_t tsize = 0, talign = 1, arch_addralign = 1;
#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
!defined (__loongarch__)
grub_size_t tramp;
+ grub_size_t tramp_align;
grub_size_t got;
+ grub_size_t got_align;
grub_err_t err;
#endif
char *ptr;
+ arch_addralign = GRUB_DL_ALIGN;
+
for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize))
{
+ grub_size_t sh_addralign;
+ grub_size_t sh_size;
+
if (s->sh_size == 0 || !(s->sh_flags & SHF_ALLOC))
continue;
- tsize = ALIGN_UP (tsize, s->sh_addralign) + s->sh_size;
- if (talign < s->sh_addralign)
- talign = s->sh_addralign;
+ sh_addralign = ALIGN_UP (s->sh_addralign, arch_addralign);
+ sh_size = ALIGN_UP (s->sh_size, sh_addralign);
+
+ tsize = ALIGN_UP (tsize, sh_addralign) + sh_size;
+ talign = grub_max (talign, sh_addralign);
}
#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
@@ -250,12 +259,12 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
if (err)
return err;
- tsize += ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN);
- if (talign < GRUB_ARCH_DL_TRAMP_ALIGN)
- talign = GRUB_ARCH_DL_TRAMP_ALIGN;
- tsize += ALIGN_UP (got, GRUB_ARCH_DL_GOT_ALIGN);
- if (talign < GRUB_ARCH_DL_GOT_ALIGN)
- talign = GRUB_ARCH_DL_GOT_ALIGN;
+ tramp_align = grub_max (GRUB_ARCH_DL_TRAMP_ALIGN, arch_addralign);
+ tsize += ALIGN_UP (tramp, tramp_align);
+ talign = grub_max (talign, tramp_align);
+ got_align = grub_max (GRUB_ARCH_DL_GOT_ALIGN, arch_addralign);
+ tsize += ALIGN_UP (got, got_align);
+ talign = grub_max (talign, got_align);
#endif
#ifdef GRUB_MACHINE_EMU
@@ -272,6 +281,9 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
i < e->e_shnum;
i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
{
+ grub_size_t sh_addralign = ALIGN_UP (s->sh_addralign, arch_addralign);
+ grub_size_t sh_size = ALIGN_UP (s->sh_size, sh_addralign);
+
if (s->sh_flags & SHF_ALLOC)
{
grub_dl_segment_t seg;
@@ -284,17 +296,18 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
{
void *addr;
- ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, s->sh_addralign);
+ ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, sh_addralign);
addr = ptr;
- ptr += s->sh_size;
+ ptr += sh_size;
switch (s->sh_type)
{
case SHT_PROGBITS:
grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size);
+ grub_memset ((char *) addr + s->sh_size, 0, sh_size -
s->sh_size);
break;
case SHT_NOBITS:
- grub_memset (addr, 0, s->sh_size);
+ grub_memset (addr, 0, sh_size);
break;
}
@@ -303,7 +316,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
else
seg->addr = 0;
- seg->size = s->sh_size;
+ seg->size = sh_size;
seg->section = i;
seg->next = mod->segment;
mod->segment = seg;
@@ -311,11 +324,11 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
}
#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
!defined (__loongarch__)
- ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN);
+ ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, tramp_align);
mod->tramp = ptr;
mod->trampptr = ptr;
ptr += tramp;
- ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_GOT_ALIGN);
+ ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, got_align);
mod->got = ptr;
mod->gotptr = ptr;
ptr += got;
diff --git a/include/grub/dl.h b/include/grub/dl.h
index 750fc8d3d..bd59bb2c4 100644
--- a/include/grub/dl.h
+++ b/include/grub/dl.h
@@ -28,6 +28,9 @@
#include <grub/list.h>
#include <grub/misc.h>
#endif
+#ifdef GRUB_MACHINE_EFI
+#include <grub/efi/memory.h>
+#endif
/*
* Macros GRUB_MOD_INIT and GRUB_MOD_FINI are also used by build rules
@@ -308,4 +311,10 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr,
grub_size_t *tramp,
#endif
+#ifdef GRUB_MACHINE_EFI
+#define GRUB_DL_ALIGN GRUB_EFI_PAGE_SIZE
+#else
+#define GRUB_DL_ALIGN 1
+#endif
+
#endif /* ! GRUB_DL_H */
--
2.39.2
- [PATCH v7 00/10] UEFI NX support and NX Linux loader using shim loader protocol, Mate Kukri, 2024/10/04
- [PATCH v7 01/10] modules: make .module_license read-only, Mate Kukri, 2024/10/04
- [PATCH v7 03/10] modules: Don't allocate space for non-allocable sections., Mate Kukri, 2024/10/04
- [PATCH v7 04/10] modules: load module sections at page-aligned addresses,
Mate Kukri <=
- [PATCH v7 05/10] nx: add memory attribute get/set API, Mate Kukri, 2024/10/04
- [PATCH v7 02/10] modules: strip .llvm_addrsig sections and similar., Mate Kukri, 2024/10/04
- [PATCH v7 06/10] nx: set page permissions for loaded modules., Mate Kukri, 2024/10/04
- [PATCH v7 07/10] nx: set the nx compatible flag in EFI GRUB images, Mate Kukri, 2024/10/04
- [PATCH v7 10/10] efi: Disallow fallback to legacy Linux loader when shim says NX is required., Mate Kukri, 2024/10/04
- [PATCH v7 08/10] efi: Provide wrappers for load_image, start_image, unload_image, Mate Kukri, 2024/10/04
- [PATCH v7 09/10] efi: Use shim's loader protocol for EFI image verification and loading, Mate Kukri, 2024/10/04