From c90e0ceec79603f90190d148bcffaee085b0a02c Mon Sep 17 00:00:00 2001
From: Vladimir Serbinenko <phcoder@gmail.com>
Date: Mon, 30 Jan 2017 00:13:41 +0000
Subject: [PATCH 6/6] grub-module-verifier: Ignore all_video emptiness on xen.

It's intentional that it's empty when no video modules
are available.
---
 grub-core/genmod.sh.in         |  2 +-
 include/grub/module_verifier.h |  4 ++--
 util/grub-module-verifier.c    | 29 +++++++++++++++++++++-----
 util/grub-module-verifierXX.c  | 38 ++++++++++++++++++++++++++++++----
 4 files changed, 61 insertions(+), 12 deletions(-)

diff --git a/grub-core/genmod.sh.in b/grub-core/genmod.sh.in
index 7f32fe82e..635fcf78e 100644
--- a/grub-core/genmod.sh.in
+++ b/grub-core/genmod.sh.in
@@ -94,6 +94,6 @@ else
 	rm -f $name.bin
 fi
 if test x@platform@ != xemu; then
-    ./build-grub-module-verifier $tmpfile @target_cpu@
+    ./build-grub-module-verifier $tmpfile @target_cpu@ @platform@
 fi
 mv $tmpfile $outfile
diff --git a/include/grub/module_verifier.h b/include/grub/module_verifier.h
index 6cddff30f..f4870cb9c 100644
--- a/include/grub/module_verifier.h
+++ b/include/grub/module_verifier.h
@@ -16,5 +16,5 @@ struct grub_module_verifier_arch {
   const int *short_relocations;
 };
 
-void grub_module_verify64(void *module_img, size_t module_size, const struct grub_module_verifier_arch *arch);
-void grub_module_verify32(void *module_img, size_t module_size, const struct grub_module_verifier_arch *arch);
+void grub_module_verify64(void *module_img, size_t module_size, const struct grub_module_verifier_arch *arch, const char **whitelist_empty);
+void grub_module_verify32(void *module_img, size_t module_size, const struct grub_module_verifier_arch *arch, const char **whitelist_empty);
diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c
index c027f0a0f..c8ae2a2f9 100644
--- a/util/grub-module-verifier.c
+++ b/util/grub-module-verifier.c
@@ -105,15 +105,27 @@ struct grub_module_verifier_arch archs[] = {
     } },
 };
 
+struct platform_whitelist {
+  const char *arch;
+  const char *platform;
+  const char **whitelist_empty;
+};
+
+static struct platform_whitelist whitelists[] = {
+  {"i386", "xen", (const char *[]) {"all_video", 0}},
+  {"x86_64", "xen", (const char *[]) {"all_video", 0}}
+};
+
 
 int
 main (int argc, char **argv)
 {
   size_t module_size;
-  unsigned arch;
+  unsigned arch, whitelist;
+  const char **whitelist_empty = 0;
   char *module_img;
-  if (argc != 3) {
-    fprintf (stderr, "usage: %s FILE ARCH\n", argv[0]);
+  if (argc != 4) {
+    fprintf (stderr, "usage: %s FILE ARCH PLATFORM\n", argv[0]);
     return 1;
   }
 
@@ -123,11 +135,18 @@ main (int argc, char **argv)
   if (arch == ARRAY_SIZE(archs))
     grub_util_error("unknown arch: %s", argv[2]);
 
+  for (whitelist = 0; whitelist < ARRAY_SIZE(whitelists); whitelist++)
+    if (strcmp(whitelists[whitelist].arch, argv[2]) == 0
+	&& strcmp(whitelists[whitelist].platform, argv[3]) == 0)
+      break;
+  if (whitelist != ARRAY_SIZE(whitelists))
+    whitelist_empty = whitelists[whitelist].whitelist_empty;
+
   module_size = grub_util_get_image_size (argv[1]);
   module_img = grub_util_read_image (argv[1]);
   if (archs[arch].voidp_sizeof == 8)
-    grub_module_verify64(module_img, module_size, &archs[arch]);
+    grub_module_verify64(module_img, module_size, &archs[arch], whitelist_empty);
   else
-    grub_module_verify32(module_img, module_size, &archs[arch]);
+    grub_module_verify32(module_img, module_size, &archs[arch], whitelist_empty);
   return 0;
 }
diff --git a/util/grub-module-verifierXX.c b/util/grub-module-verifierXX.c
index 9c04caa63..2c0c690fa 100644
--- a/util/grub-module-verifierXX.c
+++ b/util/grub-module-verifierXX.c
@@ -184,8 +184,24 @@ get_symtab (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, Elf_Word
   return sym;
 }
 
+static int
+is_whitelisted (const char *modname, const char **whitelist)
+{
+  const char **ptr;
+  if (!whitelist)
+    return 0;
+  if (!modname)
+    return 0;
+  for (ptr = whitelist; *ptr; ptr++)
+    if (strcmp (modname, *ptr) == 0)
+      return 1;
+  return 0;
+}
+
 static void
-check_symbols (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e)
+check_symbols (const struct grub_module_verifier_arch *arch,
+	       Elf_Ehdr *e, const char *modname,
+	       const char **whitelist_empty)
 {
   Elf_Sym *sym;
   Elf_Word size, entsize;
@@ -196,7 +212,16 @@ check_symbols (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e)
   sym = get_symtab (arch, e, &size, &entsize);
   if (!sym)
     {
-      Elf_Shdr *s = find_section (arch, e, ".moddeps");
+      Elf_Shdr *s;
+
+      /* However some modules are dependencies-only,
+	 e.g. insmod all_video pulls in all video drivers.
+	 Some platforms e.g. xen have no video drivers, so
+	 the module does nothing.  */
+      if (is_whitelisted (modname, whitelist_empty))
+	return;
+
+      s = find_section (arch, e, ".moddeps");
 
       if (!s)
 	grub_util_error ("no symbol table and no .moddeps section");
@@ -324,7 +349,9 @@ check_relocations (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e)
 }
 
 void
-SUFFIX(grub_module_verify) (void *module_img, size_t size, const struct grub_module_verifier_arch *arch)
+SUFFIX(grub_module_verify) (void *module_img, size_t size,
+			    const struct grub_module_verifier_arch *arch,
+			    const char **whitelist_empty)
 {
   Elf_Ehdr *e = module_img;
 
@@ -361,11 +388,14 @@ SUFFIX(grub_module_verify) (void *module_img, size_t size, const struct grub_mod
   check_license (arch, e);
 
   Elf_Shdr *s;
+  const char *modname;
 
   s = find_section (arch, e, ".modname");
   if (!s)
     grub_util_error ("no module name found");
 
-  check_symbols(arch, e);
+  modname = (const char *) e + grub_target_to_host (s->sh_offset);
+
+  check_symbols(arch, e, modname, whitelist_empty);
   check_relocations(arch, e);
 }
-- 
2.26.2

