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

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