nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

Blame SOURCES/0282-support-modules-without-symbol-table.patch

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