grub-module-verifier.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <grub/elf.h>
  4. #include <grub/module_verifier.h>
  5. #include <grub/misc.h>
  6. #include <grub/util/misc.h>
  7. struct grub_module_verifier_arch archs[] = {
  8. { "i386", 4, 0, EM_386, GRUB_MODULE_VERIFY_SUPPORTS_REL, (int[]){
  9. R_386_32,
  10. R_386_PC32,
  11. -1
  12. } },
  13. { "x86_64", 8, 0, EM_X86_64, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
  14. R_X86_64_64,
  15. R_X86_64_PC64,
  16. /* R_X86_64_32, R_X86_64_32S are supported but shouldn't be used because of their limited range. */
  17. -1
  18. }, (int[]){
  19. R_X86_64_PC32,
  20. -1
  21. }
  22. },
  23. { "powerpc", 4, 1, EM_PPC, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
  24. GRUB_ELF_R_PPC_ADDR16_LO,
  25. GRUB_ELF_R_PPC_REL24, /* It has limited range but GRUB adds trampolines when necessarry. */
  26. GRUB_ELF_R_PPC_ADDR16_HA,
  27. GRUB_ELF_R_PPC_ADDR32,
  28. GRUB_ELF_R_PPC_REL32,
  29. -1
  30. } },
  31. { "sparc64", 8, 1, EM_SPARCV9, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
  32. R_SPARC_WDISP30, /* It has limited range but GRUB adds trampolines when necessarry. */
  33. R_SPARC_HH22,
  34. R_SPARC_HM10,
  35. R_SPARC_LM22,
  36. R_SPARC_LO10,
  37. R_SPARC_64,
  38. R_SPARC_OLO10,
  39. /* Following 2 relocations have limited range but unfortunately
  40. clang generates them, as it doesn't implement mcmodel=large properly.
  41. At least our heap and core are under 4G, so it's not a problem
  42. usually. */
  43. R_SPARC_HI22,
  44. R_SPARC_32,
  45. -1
  46. } },
  47. { "ia64", 8, 0, EM_IA_64, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
  48. R_IA64_PCREL21B, /* We should verify that it's pointing either
  49. to a function or to a section in the same module.
  50. Checking that external symbol is a function is
  51. non-trivial and I have never seen this relocation used
  52. for anything else, so assume that it always points to a
  53. function.
  54. */
  55. R_IA64_SEGREL64LSB,
  56. R_IA64_FPTR64LSB,
  57. R_IA64_DIR64LSB,
  58. R_IA64_PCREL64LSB,
  59. R_IA64_LTOFF22X,
  60. R_IA64_LTOFF22,
  61. R_IA64_LTOFF_FPTR22,
  62. R_IA64_LDXMOV,
  63. -1
  64. }, (int[]){
  65. R_IA64_GPREL22,
  66. -1
  67. } },
  68. { "mipsel", 4, 0, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
  69. R_MIPS_HI16,
  70. R_MIPS_LO16,
  71. R_MIPS_32,
  72. R_MIPS_GPREL32,
  73. R_MIPS_26,
  74. R_MIPS_GOT16,
  75. R_MIPS_CALL16,
  76. R_MIPS_JALR,
  77. -1
  78. } },
  79. { "mips", 4, 1, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
  80. R_MIPS_HI16,
  81. R_MIPS_LO16,
  82. R_MIPS_32,
  83. R_MIPS_GPREL32,
  84. R_MIPS_26,
  85. R_MIPS_GOT16,
  86. R_MIPS_CALL16,
  87. R_MIPS_JALR,
  88. -1
  89. } },
  90. { "arm", 4, 0, EM_ARM, GRUB_MODULE_VERIFY_SUPPORTS_REL, (int[]){
  91. /* Some relocations are range-limited but trampolines are added when necessarry. */
  92. R_ARM_ABS32,
  93. R_ARM_CALL,
  94. R_ARM_JUMP24,
  95. R_ARM_THM_CALL,
  96. R_ARM_THM_JUMP24,
  97. R_ARM_V4BX,
  98. R_ARM_THM_MOVW_ABS_NC,
  99. R_ARM_THM_MOVT_ABS,
  100. R_ARM_THM_JUMP19,
  101. -1
  102. } },
  103. { "arm64", 8, 0, EM_AARCH64, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
  104. R_AARCH64_ABS64,
  105. R_AARCH64_CALL26,
  106. R_AARCH64_JUMP26,
  107. -1
  108. }, (int[]){
  109. R_AARCH64_ADR_PREL_PG_HI21,
  110. R_AARCH64_ADD_ABS_LO12_NC,
  111. R_AARCH64_LDST64_ABS_LO12_NC,
  112. -1
  113. }
  114. },
  115. };
  116. int
  117. main (int argc, char **argv)
  118. {
  119. size_t module_size;
  120. unsigned arch;
  121. char *module_img;
  122. if (argc != 3) {
  123. fprintf (stderr, "usage: %s FILE ARCH\n", argv[0]);
  124. return 1;
  125. }
  126. for (arch = 0; arch < ARRAY_SIZE(archs); arch++)
  127. if (strcmp(archs[arch].name, argv[2]) == 0)
  128. break;
  129. if (arch == ARRAY_SIZE(archs))
  130. grub_util_error("unknown arch: %s", argv[2]);
  131. module_size = grub_util_get_image_size (argv[1]);
  132. module_img = grub_util_read_image (argv[1]);
  133. if (archs[arch].voidp_sizeof == 8)
  134. grub_module_verify64(module_img, module_size, &archs[arch]);
  135. else
  136. grub_module_verify32(module_img, module_size, &archs[arch]);
  137. return 0;
  138. }