diff -Nru shim-15.4/debian/changelog shim-15.4/debian/changelog --- shim-15.4/debian/changelog 2021-06-16 10:52:45.000000000 +0000 +++ shim-15.4/debian/changelog 2021-07-07 08:57:35.000000000 +0000 @@ -1,3 +1,12 @@ +shim (15.4-0ubuntu7) hirsute; urgency=medium + + * Fix load option parsing, and thus fwupd execution (LP: #1929471) (PR #379) + * Fix occasional crashes in _relocate() on arm64 (LP: #1928010) (PR #383) + * Fix accidental deletion of RT variables (LP: #1934506) (PR #387) + * mok: relax the maximum variable size check (LP: #1934780) (PR #369) + + -- Julian Andres Klode Wed, 07 Jul 2021 10:57:35 +0200 + shim (15.4-0ubuntu5) hirsute; urgency=medium * Rebuild in hirsute to get a more stable target to keep shim reproducible diff -Nru shim-15.4/debian/patches/369.patch shim-15.4/debian/patches/369.patch --- shim-15.4/debian/patches/369.patch 1970-01-01 00:00:00.000000000 +0000 +++ shim-15.4/debian/patches/369.patch 2021-07-07 08:57:35.000000000 +0000 @@ -0,0 +1,41 @@ +From: Gary Lin +Date: Wed, 5 May 2021 11:25:07 +0800 +Subject: mok: relax the maximum variable size check + +Some UEFI environment such as u-boot doesn't implement +QueryVariableInfo(), so we couldn't rely on the function to estimate the +available space for RT variables. All we can do is to call SetVariable() +directly and check the return value of SetVariable(). + +Signed-off-by: Gary Lin +Origin: https://github.com/rhboot/shim/pull/369 +Bug-Ubuntuhttps://bugs.launchpad.net/bugs/1934780 +--- + mok.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/mok.c b/mok.c +index a687a92..d3d0f25 100644 +--- a/mok.c ++++ b/mok.c +@@ -362,13 +362,18 @@ mirror_mok_db(CHAR16 *name, CHAR8 *name8, EFI_GUID *guid, UINT32 attrs, + SIZE_T max_var_sz; + + efi_status = get_max_var_sz(attrs, &max_var_sz); +- if (EFI_ERROR(efi_status)) { ++ if (EFI_ERROR(efi_status) && efi_status != EFI_UNSUPPORTED) { + LogError(L"Could not get maximum variable size: %r", + efi_status); + return efi_status; + } + +- if (FullDataSize <= max_var_sz) { ++ /* Some UEFI environment such as u-boot doesn't implement ++ * QueryVariableInfo() and we will only get EFI_UNSUPPORTED when ++ * querying the available space. In this case, we just mirror ++ * the variable directly. */ ++ if (FullDataSize <= max_var_sz || efi_status == EFI_UNSUPPORTED) { ++ efi_status = EFI_SUCCESS; + if (only_first) + efi_status = SetVariable(name, guid, attrs, + FullDataSize, FullData); diff -Nru shim-15.4/debian/patches/379.patch shim-15.4/debian/patches/379.patch --- shim-15.4/debian/patches/379.patch 1970-01-01 00:00:00.000000000 +0000 +++ shim-15.4/debian/patches/379.patch 2021-07-07 08:57:35.000000000 +0000 @@ -0,0 +1,401 @@ +From: Chris Coulson +Date: Mon, 7 Jun 2021 16:34:18 +0100 +Subject: shim: another attempt to fix load options handling + +The load options handling is quite complicated and tries to accomodate +several scenarios, but there are currently multiple issues: + +- If the supplied LoadOptions is an EFI_LOAD_OPTION structure, +second_stage gets initialized to the entire contents of the OptionalData +field and load_options is initialized to NULL, which means it isn't +possible to pass additional options to the second stage loader (and it +looks like the intention is for this to be supported). + +- If the supplied LoadOptions contains 2 or more strings, the code seems +to assume that shim was executed from the UEFI shell and that the first +argument is the path of the shim executable, so it's ignored. But this +breaks the ability to pass additional options to the second stage loader +from BDS on firmware implementations that initialize LoadOptions to just +the OptionalData field of the EFI_LOAD_OPTION, which is what EDK2 seems +to do. + +This is moot anyway because this case (strings == 2) doesn't actually seem +to work, as nothing sets loader_len and therefore second_stage is not set +to the custom loader path. + +- If the supplied LoadOptions contains a single string that isn't shim's +path, nothing sets loader_len and therefore second_stage isn't set at the +end of set_second_stage. + +- set_second_stage replaces L' ' characters with L'\0' - whilst this is +useful to NULL terminate the path for the second stage, it doesn't seem +quite right to do this for the remaining LoadOptions data. Grub's +chainloader command supplies additional arguments as a NULL-terminated +space-delimited string via LoadOptions. Making it NULL-delimited seems to +be incompatible with the kernel's commandline handling, which wouldn't +work for scenarios where you might want to direct-boot a kernel image +(wrapped in systemd's EFI stub) from shim. + +- handle_image passes the original LoadOptions to the second stage if +load_options is NULL, which means that the second stage currently always +gets shim's load options. + +I've made an attempt to try to fix things. After the initial +checks in set_second_stage, it now does this: + +- Tries to parse LoadOptions as an EFI_LOAD_OPTION in order to extract +the OptionalData if it is. +- If it's not an EFI_LOAD_OPTION, check if the first string is the +current shim path and ignore it if it is (the UEFI shell case). +- Split LoadOptions in to a single NULL terminated string (used to +initialize second_stage) and the unmodified remaining data (used to +initialize load_options and load_options_size). + +I've also modified handle_image to always set LoadOptions and +LoadOptionsSize. If shim is executed with no options, or is only +executed with a single option to override the second stage loader +path, the second stage is executed with LoadOptions = NULL and +LoadOptionsSize = 0 now. + +I've tested this on EDK2 and I can load a custom loader with extra +options from both BDS and the UEFI shell: + +FS0:\> shimx64.efi test.efi +LoadOptionsSize: 0 +LoadOptions: (null) +FS0:\> shimx64.efi test.efi +LoadOptionsSize: 0 +LoadOptions: (null) +FS0:\> shimx64.efi test.efi foo bar +LoadOptionsSize: 16 +LoadOptions: foo bar + +Origin: https://github.com/rhboot/shim/pull/379 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1929471 +--- + include/ucs2.h | 27 -------- + pe.c | 6 +- + shim.c | 200 ++++++++++++++++++++++++++------------------------------- + 3 files changed, 92 insertions(+), 141 deletions(-) + +diff --git a/include/ucs2.h b/include/ucs2.h +index e43c341..ee038ce 100644 +--- a/include/ucs2.h ++++ b/include/ucs2.h +@@ -81,31 +81,4 @@ is_all_nuls(UINT8 *data, UINTN data_size) + return true; + } + +-static inline UINTN +-__attribute__((__unused__)) +-count_ucs2_strings(UINT8 *data, UINTN data_size) +-{ +- UINTN pos = 0; +- UINTN last_nul_pos = 0; +- UINTN num_nuls = 0; +- UINTN i; +- +- if (data_size % 2 != 0) +- return 0; +- +- for (i = pos; i < data_size; i++) { +- if (i % 2 != 0) { +- if (data[i] != 0) +- return 0; +- } else if (data[i] == 0) { +- last_nul_pos = i; +- num_nuls++; +- } +- pos = i; +- } +- if (num_nuls > 0 && last_nul_pos != pos - 1) +- return 0; +- return num_nuls; +-} +- + #endif /* SHIM_UCS2_H */ +diff --git a/pe.c b/pe.c +index 365e32a..13bc397 100644 +--- a/pe.c ++++ b/pe.c +@@ -1144,10 +1144,8 @@ handle_image (void *data, unsigned int datasize, + li->ImageSize = context.ImageSize; + + /* Pass the load options to the second stage loader */ +- if ( load_options ) { +- li->LoadOptions = load_options; +- li->LoadOptionsSize = load_options_size; +- } ++ li->LoadOptions = load_options; ++ li->LoadOptionsSize = load_options_size; + + if (!found_entry_point) { + perror(L"Entry point is not within sections\n"); +diff --git a/shim.c b/shim.c +index 40e4894..ecf6ee5 100644 +--- a/shim.c ++++ b/shim.c +@@ -1241,9 +1241,13 @@ EFI_STATUS init_grub(EFI_HANDLE image_handle) + return efi_status; + } + ++/* ++ * Extract the OptionalData and OptionalData fields from an ++ * EFI_LOAD_OPTION. ++ */ + static inline EFI_STATUS +-get_load_option_optional_data(UINT8 *data, UINTN data_size, +- UINT8 **od, UINTN *ods) ++get_load_option_optional_data(VOID *data, UINT32 data_size, ++ VOID **od, UINT32 *ods) + { + /* + * If it's not at least Attributes + FilePathListLength + +@@ -1253,7 +1257,8 @@ get_load_option_optional_data(UINT8 *data, UINTN data_size, + if (data_size < (sizeof(UINT32) + sizeof(UINT16) + 2 + 4)) + return EFI_INVALID_PARAMETER; + +- UINT8 *cur = data + sizeof(UINT32); ++ UINT8 *start = (UINT8 *)data; ++ UINT8 *cur = start + sizeof(UINT32); + UINT16 fplistlen = *(UINT16 *)cur; + /* + * If there's not enough space for the file path list and the +@@ -1263,8 +1268,8 @@ get_load_option_optional_data(UINT8 *data, UINTN data_size, + return EFI_INVALID_PARAMETER; + + cur += sizeof(UINT16); +- UINTN limit = data_size - (cur - data) - fplistlen; +- UINTN i; ++ UINT32 limit = data_size - (cur - start) - fplistlen; ++ UINT32 i; + for (i = 0; i < limit ; i++) { + /* If the description isn't valid UCS2-LE, it's not valid. */ + if (i % 2 != 0) { +@@ -1380,6 +1385,57 @@ done: + return ret; + } + ++/* ++ * Split the supplied load options in to a NULL terminated ++ * string representing the path of the second stage loader, ++ * and return a pointer to the remaining load options data ++ * and its remaining size. ++ * ++ * This expects the supplied load options to begin with a ++ * string that is either NULL terminated or terminated with ++ * a space and some optional data. It will return NULL if ++ * the supplied load options contains no spaces or NULL ++ * terminators. ++ */ ++static CHAR16 * ++split_load_options(VOID *in, UINT32 in_size, ++ VOID **remaining, ++ UINT32 *remaining_size) { ++ UINTN i; ++ CHAR16 *arg0 = NULL; ++ CHAR16 *start = (CHAR16 *)in; ++ ++ /* Skip spaces */ ++ for (i = 0; i < in_size / sizeof(CHAR16); i++) { ++ if (*start != L' ') ++ break; ++ ++ start++; ++ } ++ ++ in_size -= ((VOID *)start - in); ++ ++ /* ++ * Ensure that the first argument is NULL terminated by ++ * replacing L' ' with L'\0'. ++ */ ++ for (i = 0; i < in_size / sizeof(CHAR16); i++) { ++ if (start[i] == L' ' || start[i] == L'\0') { ++ start[i] = L'\0'; ++ arg0 = (CHAR16 *)start; ++ break; ++ } ++ } ++ ++ if (arg0) { ++ UINTN skip = i + 1; ++ *remaining_size = in_size - (skip * sizeof(CHAR16)); ++ *remaining = *remaining_size > 0 ? start + skip : NULL; ++ } ++ ++ return arg0; ++} ++ + /* + * Check the load options to specify the second stage loader + */ +@@ -1387,20 +1443,11 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle) + { + EFI_STATUS efi_status; + EFI_LOADED_IMAGE *li = NULL; +- CHAR16 *start = NULL; +- UINTN remaining_size = 0; ++ VOID *remaining = NULL; ++ UINT32 remaining_size; + CHAR16 *loader_str = NULL; +- UINTN loader_len = 0; +- unsigned int i; +- UINTN second_stage_len; + +- second_stage_len = (StrLen(DEFAULT_LOADER) + 1) * sizeof(CHAR16); +- second_stage = AllocatePool(second_stage_len); +- if (!second_stage) { +- perror(L"Could not allocate %lu bytes\n", second_stage_len); +- return EFI_OUT_OF_RESOURCES; +- } +- StrCpy(second_stage, DEFAULT_LOADER); ++ second_stage = DEFAULT_LOADER; + load_options = NULL; + load_options_size = 0; + +@@ -1499,105 +1546,44 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle) + return EFI_SUCCESS; + + /* +- * Check and see if this is just a list of strings. If it's an +- * EFI_LOAD_OPTION, it'll be 0, since we know EndEntire device path +- * won't pass muster as UCS2-LE. +- * +- * If there are 3 strings, we're launched from the shell most likely, +- * But we actually only care about the second one. ++ * See if this is an EFI_LOAD_OPTION and extract the optional ++ * data if it is. This will return an error if it is not a valid ++ * EFI_LOAD_OPTION. + */ +- UINTN strings = count_ucs2_strings(li->LoadOptions, +- li->LoadOptionsSize); +- +- /* +- * In some cases we get strings == 1 because BDS is using L' ' as the +- * delimeter: +- * 0000:74 00 65 00 73 00 74 00 2E 00 65 00 66 00 69 00 t.e.s.t...e.f.i. +- * 0016:20 00 6F 00 6E 00 65 00 20 00 74 00 77 00 6F 00 ..o.n.e...t.w.o. +- * 0032:20 00 74 00 68 00 72 00 65 00 65 00 00 00 ..t.h.r.e.e... +- * +- * If so replace it with NULs since the code already handles that +- * case. +- */ +- if (strings == 1) { +- UINT16 *cur = start = li->LoadOptions; +- +- /* replace L' ' with L'\0' if we find any */ +- for (i = 0; i < li->LoadOptionsSize / 2; i++) { +- if (cur[i] == L' ') +- cur[i] = L'\0'; +- } +- +- /* redo the string count */ +- strings = count_ucs2_strings(li->LoadOptions, +- li->LoadOptionsSize); +- } +- +- /* +- * If it's not string data, try it as an EFI_LOAD_OPTION. +- */ +- if (strings == 0) { +- /* +- * We at least didn't find /enough/ strings. See if it works +- * as an EFI_LOAD_OPTION. +- */ +- efi_status = get_load_option_optional_data(li->LoadOptions, +- li->LoadOptionsSize, +- (UINT8 **)&start, +- &loader_len); +- if (EFI_ERROR(efi_status)) +- return EFI_SUCCESS; +- +- remaining_size = 0; +- } else if (strings >= 2) { ++ efi_status = get_load_option_optional_data(li->LoadOptions, ++ li->LoadOptionsSize, ++ &li->LoadOptions, ++ &li->LoadOptionsSize); ++ if (EFI_ERROR(efi_status)) { + /* ++ * it's not an EFI_LOAD_OPTION, so it's probably just a string ++ * or list of strings. ++ * + * UEFI shell copies the whole line of the command into +- * LoadOptions. We ignore the string before the first L'\0', +- * i.e. the name of this program. ++ * LoadOptions. We ignore the first string, i.e. the name of this ++ * program in this case. + */ +- UINT16 *cur = li->LoadOptions; +- for (i = 1; i < li->LoadOptionsSize / 2; i++) { +- if (cur[i - 1] == L'\0') { +- start = &cur[i]; +- remaining_size = li->LoadOptionsSize - (i * 2); +- break; +- } ++ CHAR16 *loader_str = split_load_options(li->LoadOptions, ++ li->LoadOptionsSize, ++ &remaining, ++ &remaining_size); ++ ++ if (loader_str && is_our_path(li, loader_str)) { ++ li->LoadOptions = remaining; ++ li->LoadOptionsSize = remaining_size; + } +- +- remaining_size -= i * 2 + 2; +- } else if (strings == 1 && is_our_path(li, start)) { +- /* +- * And then I found a version of BDS that gives us our own path +- * in LoadOptions: +- +-77162C58 5c 00 45 00 46 00 49 00 |\.E.F.I.| +-77162C60 5c 00 42 00 4f 00 4f 00 54 00 5c 00 42 00 4f 00 |\.B.O.O.T.\.B.O.| +-77162C70 4f 00 54 00 58 00 36 00 34 00 2e 00 45 00 46 00 |O.T.X.6.4...E.F.| +-77162C80 49 00 00 00 |I...| +- +- * which is just cruel... So yeah, just don't use it. +- */ +- return EFI_SUCCESS; + } + ++ loader_str = split_load_options(li->LoadOptions, li->LoadOptionsSize, ++ &remaining, &remaining_size); ++ + /* + * Set up the name of the alternative loader and the LoadOptions for + * the loader + */ +- if (loader_len > 0) { +- /* we might not always have a NULL at the end */ +- loader_str = AllocatePool(loader_len + 2); +- if (!loader_str) { +- perror(L"Failed to allocate loader string\n"); +- return EFI_OUT_OF_RESOURCES; +- } +- +- for (i = 0; i < loader_len / 2; i++) +- loader_str[i] = start[i]; +- loader_str[loader_len/2] = L'\0'; +- ++ if (loader_str) { + second_stage = loader_str; +- load_options = remaining_size ? start + (loader_len/2) : NULL; ++ load_options = remaining; + load_options_size = remaining_size; + } + +@@ -1777,12 +1763,6 @@ shim_fini(void) + + unhook_exit(); + +- /* +- * Free the space allocated for the alternative 2nd stage loader +- */ +- if (load_options_size > 0 && second_stage) +- FreePool(second_stage); +- + console_fini(); + } + diff -Nru shim-15.4/debian/patches/383.patch shim-15.4/debian/patches/383.patch --- shim-15.4/debian/patches/383.patch 1970-01-01 00:00:00.000000000 +0000 +++ shim-15.4/debian/patches/383.patch 2021-07-07 08:57:35.000000000 +0000 @@ -0,0 +1,134 @@ +From: Gary Lin +Date: Wed, 16 Jun 2021 16:13:32 +0800 +Subject: arm/aa64: fix the size of .rela* sections + +The previous commit(*) merged .rel* and .dyn* into .rodata, and this +made ld to generate the wrong size for .rela* sections that covered +other unrelated sections. When the EFI image was loaded, _relocate() +went through the unexpected data and may cause unexpected crash. +This commit moves .rel* and .dyn* out of .rodata in the ld script but +also moves the related variables, such as _evrodata, _rodata_size, +and _rodata_vsize, to the end of the new .dyn section, so that the +crafted pe-coff section header for .rodata still covers our new +.rela and .dyn sections. + +(*) 212ba30544f ("arm/aa64 targets: put .rel* and .dyn* in .rodata") + +Fix issue: https://github.com/rhboot/shim/issues/371 + +Signed-off-by: Gary Lin + +Origin: https://github.com/rhboot/shim/pull/383 +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/shim/+bug/1928010 +--- + Makefile | 4 ++-- + elf_aarch64_efi.lds | 24 ++++++++++++++++-------- + elf_arm_efi.lds | 24 ++++++++++++++++-------- + 3 files changed, 34 insertions(+), 18 deletions(-) + +diff --git a/Makefile b/Makefile +index d18fad5..d7b60fc 100644 +--- a/Makefile ++++ b/Makefile +@@ -247,7 +247,7 @@ ifneq ($(OBJCOPY_GTE224),1) + endif + $(OBJCOPY) -D -j .text -j .sdata -j .data -j .data.ident \ + -j .dynamic -j .rodata -j .rel* \ +- -j .rela* -j .reloc -j .eh_frame \ ++ -j .rela* -j .dyn -j .reloc -j .eh_frame \ + -j .vendor_cert -j .sbat \ + $(FORMAT) $< $@ + # I am tired of wasting my time fighting binutils timestamp code. +@@ -264,7 +264,7 @@ ifneq ($(OBJCOPY_GTE224),1) + endif + $(OBJCOPY) -D -j .text -j .sdata -j .data \ + -j .dynamic -j .rodata -j .rel* \ +- -j .rela* -j .reloc -j .eh_frame -j .sbat \ ++ -j .rela* -j .dyn -j .reloc -j .eh_frame -j .sbat \ + -j .debug_info -j .debug_abbrev -j .debug_aranges \ + -j .debug_line -j .debug_str -j .debug_ranges \ + -j .note.gnu.build-id \ +diff --git a/elf_aarch64_efi.lds b/elf_aarch64_efi.lds +index 353b24a..42825fd 100644 +--- a/elf_aarch64_efi.lds ++++ b/elf_aarch64_efi.lds +@@ -70,21 +70,29 @@ SECTIONS + .rodata : + { + _rodata = .; +- *(.rela.dyn) +- *(.rela.plt) +- *(.rela.got) +- *(.rela.data) +- *(.rela.data*) +- + *(.rodata*) + *(.srodata) +- *(.dynsym) +- *(.dynstr) + . = ALIGN(16); + *(.note.gnu.build-id) + . = ALIGN(4096); + *(.vendor_cert) + *(.data.ident) ++ . = ALIGN(4096); ++ } ++ . = ALIGN(4096); ++ .rela : ++ { ++ *(.rela.dyn) ++ *(.rela.plt) ++ *(.rela.got) ++ *(.rela.data) ++ *(.rela.data*) ++ } ++ . = ALIGN(4096); ++ .dyn : ++ { ++ *(.dynsym) ++ *(.dynstr) + _evrodata = .; + . = ALIGN(4096); + } +diff --git a/elf_arm_efi.lds b/elf_arm_efi.lds +index e4e29bd..5334621 100644 +--- a/elf_arm_efi.lds ++++ b/elf_arm_efi.lds +@@ -70,21 +70,29 @@ SECTIONS + .rodata : + { + _rodata = .; +- *(.rel.dyn) +- *(.rel.plt) +- *(.rel.got) +- *(.rel.data) +- *(.rel.data*) +- + *(.rodata*) + *(.srodata) +- *(.dynsym) +- *(.dynstr) + . = ALIGN(16); + *(.note.gnu.build-id) + . = ALIGN(4096); + *(.vendor_cert) + *(.data.ident) ++ . = ALIGN(4096); ++ } ++ . = ALIGN(4096); ++ .rela : ++ { ++ *(.rela.dyn) ++ *(.rela.plt) ++ *(.rela.got) ++ *(.rela.data) ++ *(.rela.data*) ++ } ++ . = ALIGN(4096); ++ .dyn : ++ { ++ *(.dynsym) ++ *(.dynstr) + _evrodata = .; + . = ALIGN(4096); + } diff -Nru shim-15.4/debian/patches/387.patch shim-15.4/debian/patches/387.patch --- shim-15.4/debian/patches/387.patch 1970-01-01 00:00:00.000000000 +0000 +++ shim-15.4/debian/patches/387.patch 2021-07-07 08:57:35.000000000 +0000 @@ -0,0 +1,38 @@ +From: Gary Lin +Date: Wed, 30 Jun 2021 16:34:51 +0800 +Subject: mok: delete the existing RT variables only when only_first=TRUE + +For the firmware without the variable writing issues, MOK variables are +mirrored when only_first=TRUE. However, LibDeleteVariable() was called +in maybe_mirror_one_mok_variable() when only_first=FALSE, and this +could delete MOK variables that were just mirrored in the first round. + +This bug was hidden since LibDeleteVariable() deletes BS+RT+NV variables +while we mirror MOK variables as BS+RT, and the firmware refused to +delete the mirrored MOK variable due to mismatching attributes. However, +some firmwares, such as VMWare, didn't enforce the attribute check and +just deleted the variables with matched name and GUID. In such system, +MokListRT was always removed before it reached OS. + +Fixes: https://github.com/rhboot/shim/issues/386 + +Signed-off-by: Gary Lin +Origin: https://github.com/rhboot/shim/pull/387 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1934506 +--- + mok.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mok.c b/mok.c +index d3d0f25..86905a1 100644 +--- a/mok.c ++++ b/mok.c +@@ -866,7 +866,7 @@ maybe_mirror_one_mok_variable(struct mok_state_variable *v, + BOOLEAN present = FALSE; + + if (v->rtname) { +- if (!only_first && (v->flags & MOK_MIRROR_DELETE_FIRST)) { ++ if (only_first && (v->flags & MOK_MIRROR_DELETE_FIRST)) { + dprint(L"deleting \"%s\"\n", v->rtname); + efi_status = LibDeleteVariable(v->rtname, v->guid); + dprint(L"LibDeleteVariable(\"%s\",...) => %r\n", v->rtname, efi_status); diff -Nru shim-15.4/debian/patches/series shim-15.4/debian/patches/series --- shim-15.4/debian/patches/series 2021-06-16 10:52:45.000000000 +0000 +++ shim-15.4/debian/patches/series 2021-07-07 08:57:35.000000000 +0000 @@ -3,5 +3,9 @@ 362.patch 364.patch ubuntu-no-addend-vendor-dbx.patch +369.patch 372.patch 378.patch +379.patch +383.patch +387.patch