0143-shim_lock-Only-skip-loading-shim_lock-verifier-with-.patch 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. From 968de8c23c1cba0f18230f778ebcf6c412ec8ec5 Mon Sep 17 00:00:00 2001
  2. From: Dimitri John Ledkov <xnox@ubuntu.com>
  3. Date: Sat, 20 Feb 2021 17:10:34 +0000
  4. Subject: [PATCH] shim_lock: Only skip loading shim_lock verifier with explicit
  5. consent
  6. Commit 32ddc42c (efi: Only register shim_lock verifier if shim_lock
  7. protocol is found and SB enabled) reintroduced CVE-2020-15705 which
  8. previously only existed in the out-of-tree linuxefi patches and was
  9. fixed as part of the BootHole patch series.
  10. Under Secure Boot enforce loading shim_lock verifier. Allow skipping
  11. shim_lock verifier if SecureBoot/MokSBState EFI variables indicate
  12. skipping validations, or if GRUB image is built with --disable-shim-lock.
  13. Fixes: 132ddc42c (efi: Only register shim_lock verifier if shim_lock
  14. protocol is found and SB enabled)
  15. Fixes: CVE-2020-15705
  16. Fixes: CVE-2021-3418
  17. Reported-by: Dimitri John Ledkov <xnox@ubuntu.com>
  18. Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com>
  19. Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
  20. Signed-off-by: Stefan Sørensen <stefan.sorensen@spectralink.com>
  21. ---
  22. docs/grub.texi | 5 ++++-
  23. grub-core/kern/efi/sb.c | 17 ++++++++++++++++-
  24. include/grub/kernel.h | 3 ++-
  25. include/grub/util/install.h | 7 +++++--
  26. util/grub-install-common.c | 12 +++++++++---
  27. util/grub-mkimage.c | 8 +++++++-
  28. util/mkimage.c | 15 ++++++++++++++-
  29. 7 files changed, 57 insertions(+), 10 deletions(-)
  30. diff --git a/docs/grub.texi b/docs/grub.texi
  31. index bff6dfc..e302797 100644
  32. --- a/docs/grub.texi
  33. +++ b/docs/grub.texi
  34. @@ -5787,7 +5787,10 @@ secure boot chain.
  35. The GRUB, except the @command{chainloader} command, works with the UEFI secure
  36. boot and the shim. This functionality is provided by the shim_lock verifier. It
  37. is built into the @file{core.img} and is registered if the UEFI secure boot is
  38. -enabled.
  39. +enabled. The @samp{shim_lock} variable is set to @samp{y} when shim_lock verifier
  40. +is registered. If it is desired to use UEFI secure boot without shim, one can
  41. +disable shim_lock by disabling shim verification with MokSbState UEFI variable
  42. +or by building grub image with @samp{--disable-shim-lock} option.
  43. All GRUB modules not stored in the @file{core.img}, OS kernels, ACPI tables,
  44. Device Trees, etc. have to be signed, e.g, using PGP. Additionally, the commands
  45. diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
  46. index 5d7210a..41dadcd 100644
  47. --- a/grub-core/kern/efi/sb.c
  48. +++ b/grub-core/kern/efi/sb.c
  49. @@ -21,9 +21,11 @@
  50. #include <grub/efi/efi.h>
  51. #include <grub/efi/pe32.h>
  52. #include <grub/efi/sb.h>
  53. +#include <grub/env.h>
  54. #include <grub/err.h>
  55. #include <grub/file.h>
  56. #include <grub/i386/linux.h>
  57. +#include <grub/kernel.h>
  58. #include <grub/mm.h>
  59. #include <grub/types.h>
  60. #include <grub/verify.h>
  61. @@ -160,14 +162,27 @@ struct grub_file_verifier shim_lock_verifier =
  62. void
  63. grub_shim_lock_verifier_setup (void)
  64. {
  65. + struct grub_module_header *header;
  66. grub_efi_shim_lock_protocol_t *sl =
  67. grub_efi_locate_protocol (&shim_lock_guid, 0);
  68. + /* shim_lock is missing, check if GRUB image is built with --disable-shim-lock. */
  69. if (!sl)
  70. - return;
  71. + {
  72. + FOR_MODULES (header)
  73. + {
  74. + if (header->type == OBJ_TYPE_DISABLE_SHIM_LOCK)
  75. + return;
  76. + }
  77. + }
  78. + /* Secure Boot is off. Do not load shim_lock. */
  79. if (grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
  80. return;
  81. + /* Enforce shim_lock_verifier. */
  82. grub_verifier_register (&shim_lock_verifier);
  83. +
  84. + grub_env_set ("shim_lock", "y");
  85. + grub_env_export ("shim_lock");
  86. }
  87. diff --git a/include/grub/kernel.h b/include/grub/kernel.h
  88. index 133a37c..abbca5e 100644
  89. --- a/include/grub/kernel.h
  90. +++ b/include/grub/kernel.h
  91. @@ -29,7 +29,8 @@ enum
  92. OBJ_TYPE_CONFIG,
  93. OBJ_TYPE_PREFIX,
  94. OBJ_TYPE_PUBKEY,
  95. - OBJ_TYPE_DTB
  96. + OBJ_TYPE_DTB,
  97. + OBJ_TYPE_DISABLE_SHIM_LOCK
  98. };
  99. /* The module header. */
  100. diff --git a/include/grub/util/install.h b/include/grub/util/install.h
  101. index 8cb5056..11a8df8 100644
  102. --- a/include/grub/util/install.h
  103. +++ b/include/grub/util/install.h
  104. @@ -65,6 +65,8 @@
  105. N_("embed FILE as public key for signature checking"), 0}, \
  106. { "sbat", GRUB_INSTALL_OPTIONS_SBAT, N_("FILE"), 0, \
  107. N_("SBAT metadata"), 0 }, \
  108. + { "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, \
  109. + N_("disable shim_lock verifier"), 0 }, \
  110. { "verbose", 'v', 0, 0, \
  111. N_("print verbose messages."), 1 }
  112. @@ -125,7 +127,8 @@ enum grub_install_options {
  113. GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE,
  114. GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS,
  115. GRUB_INSTALL_OPTIONS_DTB,
  116. - GRUB_INSTALL_OPTIONS_SBAT
  117. + GRUB_INSTALL_OPTIONS_SBAT,
  118. + GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK
  119. };
  120. extern char *grub_install_source_directory;
  121. @@ -187,7 +190,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
  122. const struct grub_install_image_target_desc *image_target,
  123. int note,
  124. grub_compression_t comp, const char *dtb_file,
  125. - const char *sbat_path);
  126. + const char *sbat_path, const int disable_shim_lock);
  127. const struct grub_install_image_target_desc *
  128. grub_install_get_image_target (const char *arg);
  129. diff --git a/util/grub-install-common.c b/util/grub-install-common.c
  130. index 1fcccd2..13d9fe9 100644
  131. --- a/util/grub-install-common.c
  132. +++ b/util/grub-install-common.c
  133. @@ -308,6 +308,7 @@ handle_install_list (struct install_list *il, const char *val,
  134. static char **pubkeys;
  135. static size_t npubkeys;
  136. static char *sbat;
  137. +static int disable_shim_lock;
  138. static grub_compression_t compression;
  139. int
  140. @@ -344,6 +345,9 @@ grub_install_parse (int key, char *arg)
  141. sbat = xstrdup (arg);
  142. return 1;
  143. + case GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK:
  144. + disable_shim_lock = 1;
  145. + return 1;
  146. case GRUB_INSTALL_OPTIONS_VERBOSITY:
  147. verbosity++;
  148. @@ -506,10 +510,11 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
  149. " --output '%s' "
  150. " --dtb '%s' "
  151. "--sbat '%s' "
  152. - "--format '%s' --compression '%s' %s %s\n",
  153. + "--format '%s' --compression '%s' %s %s %s\n",
  154. dir, prefix,
  155. outname, dtb ? : "", sbat ? : "", mkimage_target,
  156. - compnames[compression], note ? "--note" : "", s);
  157. + compnames[compression], note ? "--note" : "",
  158. + disable_shim_lock ? "--disable-shim-lock" : "", s);
  159. free (s);
  160. tgt = grub_install_get_image_target (mkimage_target);
  161. @@ -519,7 +524,8 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
  162. grub_install_generate_image (dir, prefix, fp, outname,
  163. modules.entries, memdisk_path,
  164. pubkeys, npubkeys, config_path, tgt,
  165. - note, compression, dtb, sbat);
  166. + note, compression, dtb, sbat,
  167. + disable_shim_lock);
  168. while (dc--)
  169. grub_install_pop_module ();
  170. }
  171. diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
  172. index 75b8847..c0d5599 100644
  173. --- a/util/grub-mkimage.c
  174. +++ b/util/grub-mkimage.c
  175. @@ -82,6 +82,7 @@ static struct argp_option options[] = {
  176. {"format", 'O', N_("FORMAT"), 0, 0, 0},
  177. {"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0},
  178. {"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0},
  179. + {"disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, N_("disable shim_lock verifier"), 0},
  180. {"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
  181. { 0, 0, 0, 0, 0, 0 }
  182. };
  183. @@ -126,6 +127,7 @@ struct arguments
  184. char *config;
  185. char *sbat;
  186. int note;
  187. + int disable_shim_lock;
  188. const struct grub_install_image_target_desc *image_target;
  189. grub_compression_t comp;
  190. };
  191. @@ -233,6 +235,10 @@ argp_parser (int key, char *arg, struct argp_state *state)
  192. arguments->sbat = xstrdup (arg);
  193. break;
  194. + case GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK:
  195. + arguments->disable_shim_lock = 1;
  196. + break;
  197. +
  198. case 'v':
  199. verbosity++;
  200. break;
  201. @@ -319,7 +325,7 @@ main (int argc, char *argv[])
  202. arguments.npubkeys, arguments.config,
  203. arguments.image_target, arguments.note,
  204. arguments.comp, arguments.dtb,
  205. - arguments.sbat);
  206. + arguments.sbat, arguments.disable_shim_lock);
  207. if (grub_util_file_sync (fp) < 0)
  208. grub_util_error (_("cannot sync `%s': %s"), arguments.output ? : "stdout",
  209. diff --git a/util/mkimage.c b/util/mkimage.c
  210. index b354ec1..a26cf76 100644
  211. --- a/util/mkimage.c
  212. +++ b/util/mkimage.c
  213. @@ -870,7 +870,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
  214. size_t npubkeys, char *config_path,
  215. const struct grub_install_image_target_desc *image_target,
  216. int note, grub_compression_t comp, const char *dtb_path,
  217. - const char *sbat_path)
  218. + const char *sbat_path, int disable_shim_lock)
  219. {
  220. char *kernel_img, *core_img;
  221. size_t total_module_size, core_size;
  222. @@ -929,6 +929,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
  223. if (sbat_path != NULL && image_target->id != IMAGE_EFI)
  224. grub_util_error (_(".sbat section can be embedded into EFI images only"));
  225. + if (disable_shim_lock)
  226. + total_module_size += sizeof (struct grub_module_header);
  227. +
  228. if (config_path)
  229. {
  230. config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1);
  231. @@ -1065,6 +1068,16 @@ grub_install_generate_image (const char *dir, const char *prefix,
  232. offset += dtb_size;
  233. }
  234. + if (disable_shim_lock)
  235. + {
  236. + struct grub_module_header *header;
  237. +
  238. + header = (struct grub_module_header *) (kernel_img + offset);
  239. + header->type = grub_host_to_target32 (OBJ_TYPE_DISABLE_SHIM_LOCK);
  240. + header->size = grub_host_to_target32 (sizeof (*header));
  241. + offset += sizeof (*header);
  242. + }
  243. +
  244. if (config_path)
  245. {
  246. struct grub_module_header *header;
  247. --
  248. 2.14.2