|
|
28f7f8 |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
28f7f8 |
From: Andrei Borzenkov <arvidjaar@gmail.com>
|
|
|
28f7f8 |
Date: Wed, 3 Feb 2016 20:34:55 +0300
|
|
|
28f7f8 |
Subject: [PATCH] support modules without symbol table
|
|
|
28f7f8 |
|
|
|
28f7f8 |
all_video module does not have any code or data and exists solely for
|
|
|
28f7f8 |
.moddeps section to pull in dependencies. This makes all symbols unneeded.
|
|
|
28f7f8 |
|
|
|
28f7f8 |
While in current binutils (last released version as of this commit is 2.26)
|
|
|
28f7f8 |
``strip --strip-unneeded'' unintentionally adds section symbols for each
|
|
|
28f7f8 |
existing section, this behavior was considered a bug and changed in commit
|
|
|
28f7f8 |
14f2c699ddca1e2f706342dffc59a6c7e23e844c to completely strip symbol table
|
|
|
28f7f8 |
in this case.
|
|
|
28f7f8 |
|
|
|
28f7f8 |
Older binutils (verified with 2.17) and some other toolchains (at least
|
|
|
28f7f8 |
elftoolchain r3223M), both used in FreeBSD, remove symbol table in all_video
|
|
|
28f7f8 |
as well.
|
|
|
28f7f8 |
|
|
|
28f7f8 |
Relax run-time check and do not return error for modules without symbol table.
|
|
|
28f7f8 |
Add additional checks to module verifier to make sure such modules
|
|
|
28f7f8 |
|
|
|
28f7f8 |
a) have non-empty .moddeps section. Without either externally visible symbols
|
|
|
28f7f8 |
or .moddeps modules are completely useless and should not be built.
|
|
|
28f7f8 |
|
|
|
28f7f8 |
b) do not have any relocations.
|
|
|
28f7f8 |
|
|
|
28f7f8 |
Closes: 46986
|
|
|
28f7f8 |
|
|
|
28f7f8 |
v2: add run-time check for empty symbol table if relocations are present as
|
|
|
28f7f8 |
suggested by Vladimir.
|
|
|
28f7f8 |
---
|
|
|
28f7f8 |
grub-core/kern/dl.c | 8 +++++++-
|
|
|
28f7f8 |
util/grub-module-verifierXX.c | 18 +++++++++++++++++-
|
|
|
28f7f8 |
2 files changed, 24 insertions(+), 2 deletions(-)
|
|
|
28f7f8 |
|
|
|
28f7f8 |
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
|
|
|
28f7f8 |
index b0b0405fcbe..c45afc64950 100644
|
|
|
28f7f8 |
--- a/grub-core/kern/dl.c
|
|
|
28f7f8 |
+++ b/grub-core/kern/dl.c
|
|
|
28f7f8 |
@@ -341,8 +341,11 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
|
|
|
28f7f8 |
if (s->sh_type == SHT_SYMTAB)
|
|
|
28f7f8 |
break;
|
|
|
28f7f8 |
|
|
|
28f7f8 |
+ /* Module without symbol table may still be used to pull in dependencies.
|
|
|
28f7f8 |
+ We verify at build time that such modules do not contain any relocations
|
|
|
28f7f8 |
+ that may reference symbol table. */
|
|
|
28f7f8 |
if (i == e->e_shnum)
|
|
|
28f7f8 |
- return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table"));
|
|
|
28f7f8 |
+ return GRUB_ERR_NONE;
|
|
|
28f7f8 |
|
|
|
28f7f8 |
#ifdef GRUB_MODULES_MACHINE_READONLY
|
|
|
28f7f8 |
mod->symtab = grub_malloc (s->sh_size);
|
|
|
28f7f8 |
@@ -584,6 +587,9 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
|
|
28f7f8 |
|
|
|
28f7f8 |
if (seg)
|
|
|
28f7f8 |
{
|
|
|
28f7f8 |
+ if (!mod->symtab)
|
|
|
28f7f8 |
+ return grub_error (GRUB_ERR_BAD_MODULE, "relocation without symbol table");
|
|
|
28f7f8 |
+
|
|
|
28f7f8 |
err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg);
|
|
|
28f7f8 |
if (err)
|
|
|
28f7f8 |
return err;
|
|
|
28f7f8 |
diff --git a/util/grub-module-verifierXX.c b/util/grub-module-verifierXX.c
|
|
|
28f7f8 |
index f612d51f389..9c04caa63b4 100644
|
|
|
28f7f8 |
--- a/util/grub-module-verifierXX.c
|
|
|
28f7f8 |
+++ b/util/grub-module-verifierXX.c
|
|
|
28f7f8 |
@@ -176,7 +176,7 @@ get_symtab (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, Elf_Word
|
|
|
28f7f8 |
break;
|
|
|
28f7f8 |
|
|
|
28f7f8 |
if (i == grub_target_to_host16 (e->e_shnum))
|
|
|
28f7f8 |
- grub_util_error ("no symbol table");
|
|
|
28f7f8 |
+ return NULL;
|
|
|
28f7f8 |
|
|
|
28f7f8 |
sym = (Elf_Sym *) ((char *) e + grub_target_to_host (s->sh_offset));
|
|
|
28f7f8 |
*size = grub_target_to_host (s->sh_size);
|
|
|
28f7f8 |
@@ -191,7 +191,21 @@ check_symbols (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e)
|
|
|
28f7f8 |
Elf_Word size, entsize;
|
|
|
28f7f8 |
unsigned i;
|
|
|
28f7f8 |
|
|
|
28f7f8 |
+ /* Module without symbol table and without .moddeps section is useless
|
|
|
28f7f8 |
+ at boot time, so catch it early to prevent build errors */
|
|
|
28f7f8 |
sym = get_symtab (arch, e, &size, &entsize);
|
|
|
28f7f8 |
+ if (!sym)
|
|
|
28f7f8 |
+ {
|
|
|
28f7f8 |
+ Elf_Shdr *s = find_section (arch, e, ".moddeps");
|
|
|
28f7f8 |
+
|
|
|
28f7f8 |
+ if (!s)
|
|
|
28f7f8 |
+ grub_util_error ("no symbol table and no .moddeps section");
|
|
|
28f7f8 |
+
|
|
|
28f7f8 |
+ if (!s->sh_size)
|
|
|
28f7f8 |
+ grub_util_error ("no symbol table and empty .moddeps section");
|
|
|
28f7f8 |
+
|
|
|
28f7f8 |
+ return;
|
|
|
28f7f8 |
+ }
|
|
|
28f7f8 |
|
|
|
28f7f8 |
for (i = 0;
|
|
|
28f7f8 |
i < size / entsize;
|
|
|
28f7f8 |
@@ -243,6 +257,8 @@ section_check_relocations (const struct grub_module_verifier_arch *arch, void *e
|
|
|
28f7f8 |
Elf_Word symtabsize, symtabentsize;
|
|
|
28f7f8 |
|
|
|
28f7f8 |
symtab = get_symtab (arch, ehdr, &symtabsize, &symtabentsize);
|
|
|
28f7f8 |
+ if (!symtab)
|
|
|
28f7f8 |
+ grub_util_error ("relocation without symbol table");
|
|
|
28f7f8 |
|
|
|
28f7f8 |
for (rel = (Elf_Rel *) ((char *) ehdr + grub_target_to_host (s->sh_offset)),
|
|
|
28f7f8 |
max = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_size));
|