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

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