diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim/0013-fallback-fix-double-free-of-dp.patch b/meta-efi-secure-boot/recipes-bsp/shim/shim/0013-fallback-fix-double-free-of-dp.patch new file mode 100644 index 0000000..e9d3b47 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim/0013-fallback-fix-double-free-of-dp.patch @@ -0,0 +1,35 @@ +From 2003b828be0e0fe774e119922e81ee0bb0d2ecdd Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Wed, 9 Aug 2017 16:10:14 +0800 +Subject: [PATCH 1/2] fallback: fix double free of dp + +If the boot option recorded in csv is not in a media device path, the +corresponding full device path will be referred for creating the boot +variable. + +However, the current code logic always frees the full device path +(full_device_path) and the media device path (dp) separately. In order +to resolve this issue, always check whether dp equals to full_device_path +before freeing dp. + +Signed-off-by: Lans Zhang +--- + fallback.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fallback.c b/fallback.c +index 9b64077..2ef1b86 100644 +--- a/fallback.c ++++ b/fallback.c +@@ -482,7 +482,7 @@ add_to_boot_list(CHAR16 *dirname, CHAR16 *filename, CHAR16 *label, CHAR16 *argum + err: + if (full_device_path) + FreePool(full_device_path); +- if (dp) ++ if (dp && dp != full_device_path) + FreePool(dp); + if (fullpath) + FreePool(fullpath); +-- +2.13.2 + diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim/0014-fallback-work-around-the-issue-of-boot-option-creati.patch b/meta-efi-secure-boot/recipes-bsp/shim/shim/0014-fallback-work-around-the-issue-of-boot-option-creati.patch new file mode 100644 index 0000000..cad1cc2 --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim/0014-fallback-work-around-the-issue-of-boot-option-creati.patch @@ -0,0 +1,197 @@ +From 0fbd5a6375bbfe463979cc1958bc721353e49625 Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Fri, 11 Aug 2017 13:42:20 +0800 +Subject: [PATCH 2/2] fallback: work around the issue of boot option creation + with AMI BIOS + +AMI BIOS (e.g, Intel NUC5i3MYHE) may automatically hide and patch BootXXXX +variables with ami_masked_device_path_guid. + +Initially, the normal boot option created by fallback looks like this: +00000000 01 00 00 00 5e 00 42 00 6f 00 6f 00 74 00 6c 00 |....^.B.o.o.t.l.| +00000010 6f 00 61 00 64 00 65 00 72 00 20 00 54 00 65 00 |o.a.d.e.r. .T.e.| +00000020 73 00 74 00 20 00 28 00 36 00 34 00 2d 00 62 00 |s.t. .(.6.4.-.b.| +00000030 69 00 74 00 29 00 00 00 04 01 2a 00 01 00 00 00 |i.t.).....*.....| +00000040 00 08 00 00 00 00 00 00 00 00 08 00 00 00 00 00 |................| +00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00000060 01 01 04 04 30 00 5c 00 45 00 46 00 49 00 5c 00 |....0.\.E.F.I.\.| +00000070 42 00 4f 00 4f 00 54 00 5c 00 74 00 65 00 73 00 |B.O.O.T.\.t.e.s.| +00000080 74 00 78 00 36 00 34 00 2e 00 65 00 66 00 69 00 |t.x.6.4...e.f.i.| +00000090 00 00 7f ff 04 00 |......| +00000096 + +after reboot, fallback has to create a new one due to the previous boot +option is hidden and masked by AMI BIOS: +00000000 09 00 00 00 76 00 42 00 6f 00 6f 00 74 00 6c 00 |....v.B.o.o.t.l.| +00000010 6f 00 61 00 64 00 65 00 72 00 20 00 54 00 65 00 |o.a.d.e.r. .T.e.| +00000020 73 00 74 00 20 00 28 00 36 00 34 00 2d 00 62 00 |s.t. .(.6.4.-.b.| +00000030 69 00 74 00 29 00 00 00 01 04 14 00 e7 75 e2 99 |i.t.)........u..| +00000040 a0 75 37 4b a2 e6 c5 38 5e 6c 00 cb 7f ff 04 00 |.u7K...8^l......| +00000050 04 01 2a 00 01 00 00 00 00 08 00 00 00 00 00 00 |..*.............| +00000060 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00000070 00 00 00 00 00 00 00 00 01 01 04 04 30 00 5c 00 |............0.\.| +00000080 45 00 46 00 49 00 5c 00 42 00 4f 00 4f 00 54 00 |E.F.I.\.B.O.O.T.| +00000090 5c 00 74 00 65 00 73 00 74 00 78 00 36 00 34 00 |\.t.e.s.t.x.6.4.| +000000a0 2e 00 65 00 66 00 69 00 00 00 7f ff 04 00 |..e.f.i.......| +000000ae + +And after several reboot, fallback will have to create more boot options +because AMI BIOS corrupts the previous ones. + +We can get the valid device path if just skipping the masked device path and +its next end path. + +Signed-off-by: Lans Zhang +--- + fallback.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 109 insertions(+), 5 deletions(-) + +diff --git a/fallback.c b/fallback.c +index 2ef1b86..46894af 100644 +--- a/fallback.c ++++ b/fallback.c +@@ -287,6 +287,105 @@ add_boot_option(EFI_DEVICE_PATH *hddp, EFI_DEVICE_PATH *fulldp, + return EFI_OUT_OF_RESOURCES; + } + ++/* ++ * AMI BIOS (e.g, Intel NUC5i3MYHE) may automatically hide and patch BootXXXX ++ * variables with ami_masked_device_path_guid. We can get the valid device path ++ * if just skipping it and its next end path. ++ */ ++ ++static EFI_GUID ami_masked_device_path_guid = { ++ 0x99e275e7, 0x75a0, 0x4b37, ++ { 0xa2, 0xe6, 0xc5, 0x38, 0x5e, 0x6c, 0x0, 0xcb } ++}; ++ ++static unsigned int ++calc_masked_boot_option_size(unsigned int size) ++{ ++ return size + sizeof(EFI_DEVICE_PATH) + ++ sizeof(ami_masked_device_path_guid) + sizeof(EFI_DEVICE_PATH); ++} ++ ++static int ++check_masked_boot_option(CHAR8 *candidate, unsigned int candidate_size, ++ CHAR8 *data, unsigned int data_size) ++{ ++ /* ++ * The patched BootXXXX variables contain a hardware device path and ++ * an end path, preceding the real device path. ++ */ ++ if (calc_masked_boot_option_size(data_size) != candidate_size) ++ return 1; ++ ++ CHAR8 *cursor = candidate; ++ ++ /* Check whether the BootXXXX is patched */ ++ cursor += sizeof(UINT32) + sizeof(UINT16); ++ cursor += StrSize((CHAR16 *)cursor); ++ ++ unsigned int min_valid_size = cursor - candidate + sizeof(EFI_DEVICE_PATH); ++ ++ if (candidate_size <= min_valid_size) ++ return 1; ++ ++ EFI_DEVICE_PATH *dp = (EFI_DEVICE_PATH *)cursor; ++ unsigned int node_size = DevicePathNodeLength(dp) - sizeof(EFI_DEVICE_PATH); ++ ++ min_valid_size += node_size; ++ if (candidate_size <= min_valid_size || ++ DevicePathType(dp) != HARDWARE_DEVICE_PATH || ++ DevicePathSubType(dp) != HW_VENDOR_DP || ++ node_size != sizeof(ami_masked_device_path_guid) || ++ CompareGuid((EFI_GUID *)(cursor + sizeof(EFI_DEVICE_PATH)), ++ &ami_masked_device_path_guid)) ++ return 1; ++ ++ /* Check whether the patched guid is followed by an end path */ ++ min_valid_size += sizeof(EFI_DEVICE_PATH); ++ if (candidate_size <= min_valid_size) ++ return 1; ++ ++ dp = NextDevicePathNode(dp); ++ if (!IsDevicePathEnd(dp)) ++ return 1; ++ ++ /* ++ * OK. We may really get a masked BootXXXX variable. The next ++ * step is to test whether it is hidden. ++ */ ++ UINT32 attrs = *(UINT32 *)candidate; ++#ifndef LOAD_OPTION_HIDDEN ++# define LOAD_OPTION_HIDDEN 0x00000008 ++#endif ++ if (!(attrs & LOAD_OPTION_HIDDEN)) ++ return 1; ++ ++ attrs &= ~LOAD_OPTION_HIDDEN; ++ ++ /* Compare the field Attributes */ ++ if (attrs != *(UINT32 *)data) ++ return 1; ++ ++ /* Compare the field FilePathListLength */ ++ data += sizeof(UINT32); ++ candidate += sizeof(UINT32); ++ if (calc_masked_boot_option_size(*(UINT16 *)data) != ++ *(UINT16 *)candidate) ++ return 1; ++ ++ /* Compare the field Description */ ++ data += sizeof(UINT16); ++ candidate += sizeof(UINT16); ++ if (CompareMem(candidate, data, cursor - candidate)) ++ return 1; ++ ++ /* Compare the filed FilePathList */ ++ cursor = (CHAR8 *)NextDevicePathNode(dp); ++ data += sizeof(UINT16); ++ data += StrSize((CHAR16 *)data); ++ ++ return CompareMem(cursor, data, candidate_size - min_valid_size); ++} ++ + EFI_STATUS + find_boot_option(EFI_DEVICE_PATH *dp, EFI_DEVICE_PATH *fulldp, + CHAR16 *filename, CHAR16 *label, CHAR16 *arguments, +@@ -316,7 +415,8 @@ find_boot_option(EFI_DEVICE_PATH *dp, EFI_DEVICE_PATH *fulldp, + EFI_GUID global = EFI_GLOBAL_VARIABLE; + EFI_STATUS rc; + +- CHAR8 *candidate = AllocateZeroPool(size); ++ UINTN max_candidate_size = calc_masked_boot_option_size(size); ++ CHAR8 *candidate = AllocateZeroPool(max_candidate_size); + if (!candidate) { + FreePool(data); + return EFI_OUT_OF_RESOURCES; +@@ -328,17 +428,21 @@ find_boot_option(EFI_DEVICE_PATH *dp, EFI_DEVICE_PATH *fulldp, + varname[6] = hexmap[(bootorder[i] & 0x00f0) >> 4]; + varname[7] = hexmap[(bootorder[i] & 0x000f) >> 0]; + +- UINTN candidate_size = size; ++ UINTN candidate_size = max_candidate_size; + rc = uefi_call_wrapper(RT->GetVariable, 5, varname, &global, + NULL, &candidate_size, candidate); + if (EFI_ERROR(rc)) + continue; + +- if (candidate_size != size) ++ if (candidate_size != size) { ++ if (check_masked_boot_option(candidate, candidate_size, ++ data, size)) ++ continue; ++ } else if (CompareMem(candidate, data, size)) + continue; + +- if (CompareMem(candidate, data, size)) +- continue; ++ VerbosePrint(L"Found boot entry \"%s\" with label \"%s\" " ++ L"for file \"%s\"\n", varname, label, filename); + + /* at this point, we have duplicate data. */ + if (!first_new_option) { +-- +2.13.2 + diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim/0013-fallback-allow-to-search-.csv-in-EFI-BOOT.patch b/meta-efi-secure-boot/recipes-bsp/shim/shim/0015-fallback-allow-to-search-.csv-in-EFI-BOOT.patch similarity index 70% rename from meta-efi-secure-boot/recipes-bsp/shim/shim/0013-fallback-allow-to-search-.csv-in-EFI-BOOT.patch rename to meta-efi-secure-boot/recipes-bsp/shim/shim/0015-fallback-allow-to-search-.csv-in-EFI-BOOT.patch index a876179..404e3de 100644 --- a/meta-efi-secure-boot/recipes-bsp/shim/shim/0013-fallback-allow-to-search-.csv-in-EFI-BOOT.patch +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim/0015-fallback-allow-to-search-.csv-in-EFI-BOOT.patch @@ -1,7 +1,7 @@ -From d008d75860433bc640aaf1c2dabe5742912bdac4 Mon Sep 17 00:00:00 2001 +From 8990fdd360bc5db39e33e3a15c447bed0c1ca46e Mon Sep 17 00:00:00 2001 From: Lans Zhang Date: Mon, 24 Jul 2017 15:15:33 +0800 -Subject: [PATCH] fallback: allow to search .csv in \EFI\BOOT +Subject: [PATCH 3/5] fallback: allow to search .csv in \EFI\BOOT Signed-off-by: Lans Zhang --- @@ -9,10 +9,10 @@ Signed-off-by: Lans Zhang 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fallback.c b/fallback.c -index 5e4a396..8c408fd 100644 +index 423b3ee..b55755b 100644 --- a/fallback.c +++ b/fallback.c -@@ -729,8 +729,7 @@ find_boot_options(EFI_HANDLE device) +@@ -874,8 +874,7 @@ find_boot_options(EFI_HANDLE device) continue; } if (!StrCmp(fi->FileName, L".") || diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim/0014-fallback-don-t-set-the-csv-entry-as-the-first-boot-b.patch b/meta-efi-secure-boot/recipes-bsp/shim/shim/0016-fallback-don-t-set-the-csv-entry-as-the-first-boot-b.patch similarity index 60% rename from meta-efi-secure-boot/recipes-bsp/shim/shim/0014-fallback-don-t-set-the-csv-entry-as-the-first-boot-b.patch rename to meta-efi-secure-boot/recipes-bsp/shim/shim/0016-fallback-don-t-set-the-csv-entry-as-the-first-boot-b.patch index 03d62b8..7f23caf 100644 --- a/meta-efi-secure-boot/recipes-bsp/shim/shim/0014-fallback-don-t-set-the-csv-entry-as-the-first-boot-b.patch +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim/0016-fallback-don-t-set-the-csv-entry-as-the-first-boot-b.patch @@ -1,19 +1,19 @@ -From 9f6d9f6b7f88b9d15dd2f25ae7f16b68a980922a Mon Sep 17 00:00:00 2001 +From b992209b060f7916de20a5926788a751f1c6636f Mon Sep 17 00:00:00 2001 From: Lans Zhang Date: Tue, 1 Aug 2017 10:25:45 +0800 -Subject: [PATCH] fallback: don't set the csv entry as the first boot by +Subject: [PATCH 4/5] fallback: don't set the csv entry as the first boot by default Signed-off-by: Lans Zhang --- - fallback.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) + fallback.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fallback.c b/fallback.c -index 8c408fd..c39f280 100644 +index b55755b..2794cc1 100644 --- a/fallback.c +++ b/fallback.c -@@ -138,6 +138,11 @@ make_full_path(CHAR16 *dirname, CHAR16 *filename, CHAR16 **out, UINT64 *outlen) +@@ -199,6 +199,11 @@ make_full_path(CHAR16 *dirname, CHAR16 *filename, CHAR16 **out, UINT64 *outlen) CHAR16 *bootorder = NULL; int nbootorder = 0; @@ -25,7 +25,7 @@ index 8c408fd..c39f280 100644 EFI_DEVICE_PATH *first_new_option = NULL; VOID *first_new_option_args = NULL; UINTN first_new_option_size = 0; -@@ -199,6 +204,9 @@ add_boot_option(EFI_DEVICE_PATH *hddp, EFI_DEVICE_PATH *fulldp, +@@ -260,6 +265,9 @@ add_boot_option(EFI_DEVICE_PATH *hddp, EFI_DEVICE_PATH *fulldp, return rc; } @@ -35,7 +35,7 @@ index 8c408fd..c39f280 100644 CHAR16 *newbootorder = AllocateZeroPool(sizeof (CHAR16) * (nbootorder + 1)); if (!newbootorder) -@@ -414,7 +422,7 @@ add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 * +@@ -569,7 +577,7 @@ add_to_boot_list(CHAR16 *dirname, CHAR16 *filename, CHAR16 *label, CHAR16 *argum rc = find_boot_option(dp, full_device_path, fullpath, label, arguments, &option); if (EFI_ERROR(rc)) { add_boot_option(dp, full_device_path, fullpath, label, arguments); @@ -44,6 +44,15 @@ index 8c408fd..c39f280 100644 CHAR16 *newbootorder; newbootorder = AllocateZeroPool(sizeof (CHAR16) * nbootorder); if (!newbootorder) +@@ -899,7 +907,7 @@ find_boot_options(EFI_HANDLE device) + + } while (1); + +- if (rc == EFI_SUCCESS && nbootorder > 0) ++ if (run_as_first_boot && rc == EFI_SUCCESS && nbootorder > 0) + rc = update_boot_order(); + + uefi_call_wrapper(fh2->Close, 1, fh2); -- 2.7.5 diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim/0017-fallback-always-try-to-boot-the-option-recorded-in-c.patch b/meta-efi-secure-boot/recipes-bsp/shim/shim/0017-fallback-always-try-to-boot-the-option-recorded-in-c.patch new file mode 100644 index 0000000..470693b --- /dev/null +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim/0017-fallback-always-try-to-boot-the-option-recorded-in-c.patch @@ -0,0 +1,36 @@ +From 92ed1e297632a718d1392c8d163beb713c00ccbf Mon Sep 17 00:00:00 2001 +From: Lans Zhang +Date: Wed, 9 Aug 2017 16:29:08 +0800 +Subject: [PATCH 5/5] fallback: always try to boot the option recorded in csv + +We intend to use fallback to work around MSFT for the next bootloader +of shim. Thus, we don't mind fallback is involved for PCR measurement +at all. + +Signed-off-by: Lans Zhang +--- + fallback.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/fallback.c b/fallback.c +index 2794cc1..0a645a4 100644 +--- a/fallback.c ++++ b/fallback.c +@@ -1016,13 +1016,7 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) + return rc; + } + +- rc = fallback_should_prefer_reset(); +- if (EFI_ERROR(rc)) { +- VerbosePrint(L"tpm not present, starting the first image\n"); +- try_start_first_option(image); +- } else { +- VerbosePrint(L"tpm present, resetting system\n"); +- } ++ try_start_first_option(image); + + Print(L"Reset System\n"); + +-- +2.7.5 + diff --git a/meta-efi-secure-boot/recipes-bsp/shim/shim_git.bb b/meta-efi-secure-boot/recipes-bsp/shim/shim_git.bb index 6e21cf8..001de7d 100644 --- a/meta-efi-secure-boot/recipes-bsp/shim/shim_git.bb +++ b/meta-efi-secure-boot/recipes-bsp/shim/shim_git.bb @@ -31,8 +31,11 @@ SRC_URI = "\ file://0010-Makefile-do-not-sign-the-efi-file.patch \ file://0011-Update-verification_method-if-the-loaded-image-is-si.patch;apply=0 \ file://0012-netboot-replace-the-depreciated-EFI_PXE_BASE_CODE.patch \ - file://0013-fallback-allow-to-search-.csv-in-EFI-BOOT.patch \ - file://0014-fallback-don-t-set-the-csv-entry-as-the-first-boot-b.patch \ + file://0013-fallback-fix-double-free-of-dp.patch \ + file://0014-fallback-work-around-the-issue-of-boot-option-creati.patch \ + file://0015-fallback-allow-to-search-.csv-in-EFI-BOOT.patch \ + file://0016-fallback-don-t-set-the-csv-entry-as-the-first-boot-b.patch \ + file://0017-fallback-always-try-to-boot-the-option-recorded-in-c.patch \ " SRC_URI_append_x86-64 = "\ ${@bb.utils.contains('DISTRO_FEATURES', 'msft', \