0141-util-mkimage-Add-an-option-to-import-SBAT-metadata-i.patch 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. From b11547137703bbc642114a816233a5b6fed61b06 Mon Sep 17 00:00:00 2001
  2. From: Peter Jones <pjones@redhat.com>
  3. Date: Mon, 15 Feb 2021 17:07:00 +0100
  4. Subject: [PATCH] util/mkimage: Add an option to import SBAT metadata into a
  5. .sbat section
  6. Add a --sbat option to the grub-mkimage tool which allows us to import
  7. an SBAT metadata formatted as a CSV file into a .sbat section of the
  8. EFI binary.
  9. Signed-off-by: Peter Jones <pjones@redhat.com>
  10. Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
  11. Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
  12. Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
  13. ---
  14. docs/grub.texi | 19 +++++++++++++++++++
  15. include/grub/util/install.h | 3 ++-
  16. include/grub/util/mkimage.h | 1 +
  17. util/grub-install-common.c | 2 +-
  18. util/grub-mkimage.c | 15 ++++++++++++++-
  19. util/mkimage.c | 43 ++++++++++++++++++++++++++++++++++++-------
  20. 6 files changed, 73 insertions(+), 10 deletions(-)
  21. diff --git a/docs/grub.texi b/docs/grub.texi
  22. index 8518cc0..bff6dfc 100644
  23. --- a/docs/grub.texi
  24. +++ b/docs/grub.texi
  25. @@ -5616,6 +5616,7 @@ environment variables and commands are listed in the same order.
  26. * Authentication and authorisation:: Users and access control
  27. * Using digital signatures:: Booting digitally signed code
  28. * UEFI secure boot and shim:: Booting digitally signed PE files
  29. +* Secure Boot Advanced Targeting:: Embedded information for generation number based revocation
  30. * Measured Boot:: Measuring boot components
  31. * Lockdown:: Lockdown when booting on a secure setup
  32. @end menu
  33. @@ -5795,6 +5796,24 @@ and @command{memrw} will not be available when the UEFI secure boot is enabled.
  34. This is done for security reasons and are enforced by the GRUB Lockdown mechanism
  35. (@pxref{Lockdown}).
  36. +@node Secure Boot Advanced Targeting
  37. +@section Embedded information for generation number based revocation
  38. +
  39. +The Secure Boot Advanced Targeting (SBAT) is a mechanism to allow the revocation
  40. +of components in the boot path by using generation numbers embedded into the EFI
  41. +binaries. The SBAT metadata is located in an .sbat data section that has set of
  42. +UTF-8 strings as comma-separated values (CSV). See
  43. +@uref{https://github.com/rhboot/shim/blob/main/SBAT.md} for more details.
  44. +
  45. +To add a data section containing the SBAT information into the binary, the
  46. +@option{--sbat} option of @command{grub-mkimage} command should be used. The content
  47. +of a CSV file, encoded with UTF-8, is copied as is to the .sbat data section into
  48. +the generated EFI binary. The CSV file can be stored anywhere on the file system.
  49. +
  50. +@example
  51. +grub-mkimage -O x86_64-efi -o grubx64.efi -p '(tftp)/grub' --sbat sbat.csv efinet tftp
  52. +@end example
  53. +
  54. @node Measured Boot
  55. @section Measuring boot components
  56. diff --git a/include/grub/util/install.h b/include/grub/util/install.h
  57. index 2631b10..c03befd 100644
  58. --- a/include/grub/util/install.h
  59. +++ b/include/grub/util/install.h
  60. @@ -183,7 +183,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
  61. char *config_path,
  62. const struct grub_install_image_target_desc *image_target,
  63. int note,
  64. - grub_compression_t comp, const char *dtb_file);
  65. + grub_compression_t comp, const char *dtb_file,
  66. + const char *sbat_path);
  67. const struct grub_install_image_target_desc *
  68. grub_install_get_image_target (const char *arg);
  69. diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h
  70. index ba9f568..3819a67 100644
  71. --- a/include/grub/util/mkimage.h
  72. +++ b/include/grub/util/mkimage.h
  73. @@ -24,6 +24,7 @@ struct grub_mkimage_layout
  74. size_t exec_size;
  75. size_t kernel_size;
  76. size_t bss_size;
  77. + size_t sbat_size;
  78. grub_uint64_t start_address;
  79. void *reloc_section;
  80. size_t reloc_size;
  81. diff --git a/util/grub-install-common.c b/util/grub-install-common.c
  82. index 0295d40..5d43ed1 100644
  83. --- a/util/grub-install-common.c
  84. +++ b/util/grub-install-common.c
  85. @@ -511,7 +511,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
  86. grub_install_generate_image (dir, prefix, fp, outname,
  87. modules.entries, memdisk_path,
  88. pubkeys, npubkeys, config_path, tgt,
  89. - note, compression, dtb);
  90. + note, compression, dtb, NULL);
  91. while (dc--)
  92. grub_install_pop_module ();
  93. }
  94. diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
  95. index 912564e..75b8847 100644
  96. --- a/util/grub-mkimage.c
  97. +++ b/util/grub-mkimage.c
  98. @@ -81,6 +81,7 @@ static struct argp_option options[] = {
  99. {"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0},
  100. {"format", 'O', N_("FORMAT"), 0, 0, 0},
  101. {"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0},
  102. + {"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0},
  103. {"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
  104. { 0, 0, 0, 0, 0, 0 }
  105. };
  106. @@ -123,6 +124,7 @@ struct arguments
  107. size_t npubkeys;
  108. char *font;
  109. char *config;
  110. + char *sbat;
  111. int note;
  112. const struct grub_install_image_target_desc *image_target;
  113. grub_compression_t comp;
  114. @@ -224,6 +226,13 @@ argp_parser (int key, char *arg, struct argp_state *state)
  115. arguments->prefix = xstrdup (arg);
  116. break;
  117. + case 's':
  118. + if (arguments->sbat)
  119. + free (arguments->sbat);
  120. +
  121. + arguments->sbat = xstrdup (arg);
  122. + break;
  123. +
  124. case 'v':
  125. verbosity++;
  126. break;
  127. @@ -309,7 +318,8 @@ main (int argc, char *argv[])
  128. arguments.memdisk, arguments.pubkeys,
  129. arguments.npubkeys, arguments.config,
  130. arguments.image_target, arguments.note,
  131. - arguments.comp, arguments.dtb);
  132. + arguments.comp, arguments.dtb,
  133. + arguments.sbat);
  134. if (grub_util_file_sync (fp) < 0)
  135. grub_util_error (_("cannot sync `%s': %s"), arguments.output ? : "stdout",
  136. @@ -328,5 +338,8 @@ main (int argc, char *argv[])
  137. if (arguments.output)
  138. free (arguments.output);
  139. + if (arguments.sbat)
  140. + free (arguments.sbat);
  141. +
  142. return 0;
  143. }
  144. diff --git a/util/mkimage.c b/util/mkimage.c
  145. index 8b475a6..b354ec1 100644
  146. --- a/util/mkimage.c
  147. +++ b/util/mkimage.c
  148. @@ -869,12 +869,13 @@ grub_install_generate_image (const char *dir, const char *prefix,
  149. char *memdisk_path, char **pubkey_paths,
  150. size_t npubkeys, char *config_path,
  151. const struct grub_install_image_target_desc *image_target,
  152. - int note, grub_compression_t comp, const char *dtb_path)
  153. + int note, grub_compression_t comp, const char *dtb_path,
  154. + const char *sbat_path)
  155. {
  156. char *kernel_img, *core_img;
  157. size_t total_module_size, core_size;
  158. size_t memdisk_size = 0, config_size = 0;
  159. - size_t prefix_size = 0, dtb_size = 0;
  160. + size_t prefix_size = 0, dtb_size = 0, sbat_size = 0;
  161. char *kernel_path;
  162. size_t offset;
  163. struct grub_util_path_list *path_list, *p;
  164. @@ -925,6 +926,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
  165. total_module_size += dtb_size + sizeof (struct grub_module_header);
  166. }
  167. + if (sbat_path != NULL && image_target->id != IMAGE_EFI)
  168. + grub_util_error (_(".sbat section can be embedded into EFI images only"));
  169. +
  170. if (config_path)
  171. {
  172. config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1);
  173. @@ -1289,8 +1293,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
  174. break;
  175. case IMAGE_EFI:
  176. {
  177. - char *pe_img, *header;
  178. + char *pe_img, *pe_sbat, *header;
  179. struct grub_pe32_section_table *section;
  180. + size_t n_sections = 4;
  181. size_t scn_size;
  182. grub_uint32_t vma, raw_data;
  183. size_t pe_size, header_size;
  184. @@ -1305,8 +1310,15 @@ grub_install_generate_image (const char *dir, const char *prefix,
  185. header_size = EFI64_HEADER_SIZE;
  186. vma = raw_data = header_size;
  187. +
  188. + if (sbat_path != NULL)
  189. + {
  190. + sbat_size = ALIGN_ADDR (grub_util_get_image_size (sbat_path));
  191. + sbat_size = ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT);
  192. + }
  193. +
  194. pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) +
  195. - ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT);
  196. + ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT) + sbat_size;
  197. header = pe_img = xcalloc (1, pe_size);
  198. memcpy (pe_img + raw_data, core_img, core_size);
  199. @@ -1321,7 +1333,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
  200. + GRUB_PE32_SIGNATURE_SIZE);
  201. c->machine = grub_host_to_target16 (image_target->pe_target);
  202. - c->num_sections = grub_host_to_target16 (4);
  203. + if (sbat_path != NULL)
  204. + n_sections++;
  205. +
  206. + c->num_sections = grub_host_to_target16 (n_sections);
  207. c->time = grub_host_to_target32 (STABLE_EMBEDDING_TIMESTAMP);
  208. c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE
  209. | GRUB_PE32_LINE_NUMS_STRIPPED
  210. @@ -1383,7 +1398,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
  211. GRUB_PE32_SCN_MEM_READ);
  212. scn_size = ALIGN_UP (layout.kernel_size - layout.exec_size, GRUB_PE32_FILE_ALIGNMENT);
  213. - PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size +
  214. + /* ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT) is done earlier. */
  215. + PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size + sbat_size +
  216. ALIGN_UP (total_module_size,
  217. GRUB_PE32_FILE_ALIGNMENT));
  218. @@ -1394,7 +1410,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
  219. GRUB_PE32_SCN_MEM_READ |
  220. GRUB_PE32_SCN_MEM_WRITE);
  221. - scn_size = pe_size - layout.reloc_size - raw_data;
  222. + scn_size = pe_size - layout.reloc_size - sbat_size - raw_data;
  223. section = init_pe_section (image_target, section, "mods",
  224. &vma, scn_size, image_target->section_align,
  225. &raw_data, scn_size,
  226. @@ -1402,6 +1418,19 @@ grub_install_generate_image (const char *dir, const char *prefix,
  227. GRUB_PE32_SCN_MEM_READ |
  228. GRUB_PE32_SCN_MEM_WRITE);
  229. + if (sbat_path != NULL)
  230. + {
  231. + pe_sbat = pe_img + raw_data;
  232. + grub_util_load_image (sbat_path, pe_sbat);
  233. +
  234. + section = init_pe_section (image_target, section, ".sbat",
  235. + &vma, sbat_size,
  236. + image_target->section_align,
  237. + &raw_data, sbat_size,
  238. + GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
  239. + GRUB_PE32_SCN_MEM_READ);
  240. + }
  241. +
  242. scn_size = layout.reloc_size;
  243. PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (vma);
  244. PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (scn_size);
  245. --
  246. 2.14.2