5 #include <grub/module_verifier.h>
7 #include <grub/util/misc.h>
9 struct grub_module_verifier_arch archs[] = {
10 { "i386", 4, 0, EM_386, GRUB_MODULE_VERIFY_SUPPORTS_REL, (int[]){
15 { "x86_64", 8, 0, EM_X86_64, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
18 /* R_X86_64_32, R_X86_64_32S are supported but shouldn't be used because of their limited range. */
26 { "powerpc", 4, 1, EM_PPC, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
27 GRUB_ELF_R_PPC_ADDR16_LO,
28 GRUB_ELF_R_PPC_REL24, /* It has limited range but GRUB adds trampolines when necessarry. */
29 GRUB_ELF_R_PPC_ADDR16_HA,
30 GRUB_ELF_R_PPC_ADDR32,
34 { "sparc64", 8, 1, EM_SPARCV9, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
35 R_SPARC_WDISP30, /* It has limited range but GRUB adds trampolines when necessarry. */
42 /* Following 2 relocations have limited range but unfortunately
43 clang generates them, as it doesn't implement mcmodel=large properly.
44 At least our heap and core are under 4G, so it's not a problem
50 { "ia64", 8, 0, EM_IA_64, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
51 R_IA64_PCREL21B, /* We should verify that it's pointing either
52 to a function or to a section in the same module.
53 Checking that external symbol is a function is
54 non-trivial and I have never seen this relocation used
55 for anything else, so assume that it always points to a
72 { "mipsel", 4, 0, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
83 { "mips", 4, 1, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
94 { "arm", 4, 0, EM_ARM, GRUB_MODULE_VERIFY_SUPPORTS_REL, (int[]){
95 /* Some relocations are range-limited but trampolines are added when necessarry. */
102 R_ARM_THM_MOVW_ABS_NC,
107 { "arm64", 8, 0, EM_AARCH64, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
111 R_AARCH64_ADR_GOT_PAGE,
112 R_AARCH64_LD64_GOT_LO12_NC,
115 R_AARCH64_ADR_PREL_PG_HI21,
116 R_AARCH64_ADD_ABS_LO12_NC,
117 R_AARCH64_LDST64_ABS_LO12_NC,
124 struct platform_whitelist {
126 const char *platform;
127 const char **whitelist_empty;
130 static struct platform_whitelist whitelists[] = {
131 {"i386", "xen", (const char *[]) {"all_video", 0}},
132 {"x86_64", "xen", (const char *[]) {"all_video", 0}},
133 {"sparc64", "ieee1275", (const char *[]) {"all_video", 0}},
135 /* video is compiled-in on MIPS. */
136 {"mipsel", "loongson", (const char *[]) {"all_video", 0}},
137 {"mipsel", "qemu_mips", (const char *[]) {"all_video", 0}},
138 {"mipsel", "arc", (const char *[]) {"all_video", 0}},
139 {"mips", "qemu_mips", (const char *[]) {"all_video", 0}},
140 {"mips", "arc", (const char *[]) {"all_video", 0}},
145 main (int argc, char **argv)
148 unsigned arch, whitelist;
149 const char **whitelist_empty = 0;
152 fprintf (stderr, "usage: %s FILE ARCH PLATFORM\n", argv[0]);
156 for (arch = 0; arch < ARRAY_SIZE(archs); arch++)
157 if (strcmp(archs[arch].name, argv[2]) == 0)
159 if (arch == ARRAY_SIZE(archs))
160 grub_util_error("unknown arch: %s", argv[2]);
162 for (whitelist = 0; whitelist < ARRAY_SIZE(whitelists); whitelist++)
163 if (strcmp(whitelists[whitelist].arch, argv[2]) == 0
164 && strcmp(whitelists[whitelist].platform, argv[3]) == 0)
166 if (whitelist != ARRAY_SIZE(whitelists))
167 whitelist_empty = whitelists[whitelist].whitelist_empty;
169 module_size = grub_util_get_image_size (argv[1]);
170 module_img = grub_util_read_image (argv[1]);
171 if (archs[arch].voidp_sizeof == 8)
172 grub_module_verify64(module_img, module_size, &archs[arch], whitelist_empty);
174 grub_module_verify32(module_img, module_size, &archs[arch], whitelist_empty);