diff --git a/0001-SBAT-Policy-latest-should-be-a-one-shot.patch b/0001-SBAT-Policy-latest-should-be-a-one-shot.patch new file mode 100644 index 0000000..65f9d4f --- /dev/null +++ b/0001-SBAT-Policy-latest-should-be-a-one-shot.patch @@ -0,0 +1,69 @@ +From 77144e5a404df89b45941bfc54fd2f59e0ee607b Mon Sep 17 00:00:00 2001 +From: Jan Setje-Eilers +Date: Tue, 24 May 2022 11:49:44 -0700 +Subject: [PATCH 1/6] SBAT Policy latest should be a one-shot + +Since booting from removable media can be hard to detect, +setting a persistent latest SBAT policy is risky in a typical +client system. This changes latest to be a one-shot operation +that could be set at the time of an OS update if desired. + +Signed-off-by: Jan Setje-Eilers +--- + sbat.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +diff --git a/sbat.c b/sbat.c +index 637df5ecdd6..9b872082e35 100644 +--- a/sbat.c ++++ b/sbat.c +@@ -369,6 +369,16 @@ preserve_sbat_uefi_variable(UINT8 *sbat, UINTN sbatsize, UINT32 attributes, + return false; + } + ++static void ++clear_sbat_policy() ++{ ++ EFI_STATUS efi_status = EFI_SUCCESS; ++ ++ efi_status = del_variable(SBAT_POLICY, SHIM_LOCK_GUID); ++ if (EFI_ERROR(efi_status)) ++ console_error(L"Could not reset SBAT Policy", efi_status); ++} ++ + EFI_STATUS + set_sbat_uefi_variable(void) + { +@@ -394,6 +404,7 @@ set_sbat_uefi_variable(void) + case SBAT_POLICY_LATEST: + dprint("Custom sbat policy: latest\n"); + sbat_var = SBAT_VAR_LATEST; ++ clear_sbat_policy(); + break; + case SBAT_POLICY_PREVIOUS: + dprint("Custom sbat policy: previous\n"); +@@ -408,19 +419,13 @@ set_sbat_uefi_variable(void) + reset_sbat = true; + sbat_var = SBAT_VAR_ORIGINAL; + } +- efi_status = del_variable(SBAT_POLICY, SHIM_LOCK_GUID); +- if (EFI_ERROR(efi_status)) +- console_error(L"Could not reset SBAT Policy", +- efi_status); ++ clear_sbat_policy(); + break; + default: + console_error(L"SBAT policy state %llu is invalid", + EFI_INVALID_PARAMETER); +- efi_status = del_variable(SBAT_POLICY, SHIM_LOCK_GUID); +- if (EFI_ERROR(efi_status)) +- console_error(L"Could not reset SBAT Policy", +- efi_status); + sbat_var = SBAT_VAR_PREVIOUS; ++ clear_sbat_policy(); + break; + } + } +-- +2.35.1 + diff --git a/0002-pe-Fix-a-buffer-overflow-when-SizeOfRawData-VirtualS.patch b/0002-pe-Fix-a-buffer-overflow-when-SizeOfRawData-VirtualS.patch new file mode 100644 index 0000000..3a3911a --- /dev/null +++ b/0002-pe-Fix-a-buffer-overflow-when-SizeOfRawData-VirtualS.patch @@ -0,0 +1,63 @@ +From e99bdbb827a50cde019393d3ca1e89397db221a7 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +Date: Tue, 3 May 2022 15:41:00 +0200 +Subject: [PATCH 2/6] pe: Fix a buffer overflow when SizeOfRawData > + VirtualSize + +During image loading, the size of the destination buffer for the image +is determined by the SizeOfImage field in the optional header. The start +and end virtual addresses of each section, as determined by each section's +VirtualAddress and VirtualSize fields, are bounds checked against the +allocated buffer. However, the amount of data copied to the destination +buffer is determined by the section's SizeOfRawData filed. If this is +larger than the VirtualSize, then the copy can overflow the destination +buffer. + +Fix this by limiting the amount of data to copy to the section's +VirtualSize. In the case where a section has SizeOfRawData > VirtualSize, +the excess data is discarded. + +This fixes CVE-2022-28737 + +Signed-off-by: Chris Coulson +--- + pe.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/pe.c b/pe.c +index 5d0c6b0bad0..1eb3f59a4f7 100644 +--- a/pe.c ++++ b/pe.c +@@ -1089,6 +1089,7 @@ handle_image (void *data, unsigned int datasize, + int i; + EFI_IMAGE_SECTION_HEADER *Section; + char *base, *end; ++ UINT32 size; + PE_COFF_LOADER_IMAGE_CONTEXT context; + unsigned int alignment, alloc_size; + int found_entry_point = 0; +@@ -1274,13 +1275,15 @@ handle_image (void *data, unsigned int datasize, + return EFI_UNSUPPORTED; + } + +- if (Section->SizeOfRawData > 0) +- CopyMem(base, data + Section->PointerToRawData, +- Section->SizeOfRawData); ++ size = Section->Misc.VirtualSize; ++ if (size > Section->SizeOfRawData) ++ size = Section->SizeOfRawData; + +- if (Section->SizeOfRawData < Section->Misc.VirtualSize) +- ZeroMem(base + Section->SizeOfRawData, +- Section->Misc.VirtualSize - Section->SizeOfRawData); ++ if (size > 0) ++ CopyMem(base, data + Section->PointerToRawData, size); ++ ++ if (size < Section->Misc.VirtualSize) ++ ZeroMem(base + size, Section->Misc.VirtualSize - size); + } + } + +-- +2.35.1 + diff --git a/0003-pe-Perform-image-verification-earlier-when-loading-g.patch b/0003-pe-Perform-image-verification-earlier-when-loading-g.patch new file mode 100644 index 0000000..a8d936d --- /dev/null +++ b/0003-pe-Perform-image-verification-earlier-when-loading-g.patch @@ -0,0 +1,78 @@ +From 5a82d7973656c68f006aac1ed462e7bb37075d92 Mon Sep 17 00:00:00 2001 +From: Chris Coulson +Date: Tue, 3 May 2022 16:02:19 +0200 +Subject: [PATCH 3/6] pe: Perform image verification earlier when loading grub + +The second stage loader was being verified after loading it into +memory. As an additional hardening measure to avoid performing risky +memcpys using header fields from a potentially specially crafted image, +perform the verification before this so that it can be rejected earlier. + +Signed-off-by: Chris Coulson +--- + pe.c | 42 +++++++++++++++++++++++++----------------- + 1 file changed, 25 insertions(+), 17 deletions(-) + +diff --git a/pe.c b/pe.c +index 1eb3f59a4f7..1d120f2d78d 100644 +--- a/pe.c ++++ b/pe.c +@@ -1106,7 +1106,31 @@ handle_image (void *data, unsigned int datasize, + } + + /* +- * We only need to verify the binary if we're in secure mode ++ * Perform the image verification before we start copying data around ++ * in order to load it. ++ */ ++ if (secure_mode ()) { ++ efi_status = verify_buffer(data, datasize, &context, sha256hash, ++ sha1hash); ++ ++ if (EFI_ERROR(efi_status)) { ++ if (verbose) ++ console_print(L"Verification failed: %r\n", efi_status); ++ else ++ console_error(L"Verification failed", efi_status); ++ return efi_status; ++ } else { ++ if (verbose) ++ console_print(L"Verification succeeded\n"); ++ } ++ } ++ ++ /* ++ * Calculate the hash for the TPM measurement. ++ * XXX: We're computing these twice in secure boot mode when the ++ * buffers already contain the previously computed hashes. Also, ++ * this is only useful for the TPM1.2 case. We should try to fix ++ * this in a follow-up. + */ + efi_status = generate_hash(data, datasize, &context, sha256hash, + sha1hash); +@@ -1287,22 +1311,6 @@ handle_image (void *data, unsigned int datasize, + } + } + +- if (secure_mode ()) { +- efi_status = verify_buffer(data, datasize, &context, sha256hash, +- sha1hash); +- +- if (EFI_ERROR(efi_status)) { +- if (verbose) +- console_print(L"Verification failed: %r\n", efi_status); +- else +- console_error(L"Verification failed", efi_status); +- return efi_status; +- } else { +- if (verbose) +- console_print(L"Verification succeeded\n"); +- } +- } +- + if (context.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { + perror(L"Image has no relocation entry\n"); + FreePool(buffer); +-- +2.35.1 + diff --git a/0004-Update-advertised-sbat-generation-number-for-shim.patch b/0004-Update-advertised-sbat-generation-number-for-shim.patch new file mode 100644 index 0000000..12804f4 --- /dev/null +++ b/0004-Update-advertised-sbat-generation-number-for-shim.patch @@ -0,0 +1,21 @@ +From 80e34fc3d55106680a245f6338bec627114bed35 Mon Sep 17 00:00:00 2001 +From: Jan Setje-Eilers +Date: Tue, 10 May 2022 13:14:24 -0700 +Subject: [PATCH 4/6] Update advertised sbat generation number for shim + +Signed-off-by: Jan Setje-Eilers +--- + data/sbat.csv | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/data/sbat.csv b/data/sbat.csv +index ad838f2aff3..7a5169fb39f 100755 +--- a/data/sbat.csv ++++ b/data/sbat.csv +@@ -1,2 +1,2 @@ + sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md +-shim,1,UEFI shim,shim,1,https://github.com/rhboot/shim ++shim,2,UEFI shim,shim,1,https://github.com/rhboot/shim +-- +2.35.1 + diff --git a/0005-Update-SBAT-generation-requirements-for-05-24-22.patch b/0005-Update-SBAT-generation-requirements-for-05-24-22.patch new file mode 100644 index 0000000..d35755d --- /dev/null +++ b/0005-Update-SBAT-generation-requirements-for-05-24-22.patch @@ -0,0 +1,31 @@ +From 9a09faf390eea083c3bef1b07c7e043ebe0cc1f6 Mon Sep 17 00:00:00 2001 +From: Jan Setje-Eilers +Date: Tue, 10 May 2022 14:09:26 -0700 +Subject: [PATCH 5/6] Update SBAT generation requirements for 05/24/22 + +bump shim SBAT generation requirement to 2 for CVE-2022-28737 +bump GRUB2 SBAT generation requirement to 2 for CVE-2021-3695 + +Signed-off-by: Jan Setje-Eilers +--- + include/sbat.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/sbat.h b/include/sbat.h +index 904880decfb..aca4359870f 100644 +--- a/include/sbat.h ++++ b/include/sbat.h +@@ -31,8 +31,8 @@ + SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_PREVIOUS_DATE "\n" \ + SBAT_VAR_PREVIOUS_REVOCATIONS + +-#define SBAT_VAR_LATEST_DATE SBAT_VAR_ORIGINAL_DATE +-#define SBAT_VAR_LATEST_REVOCATIONS ++#define SBAT_VAR_LATEST_DATE "2022052400" ++#define SBAT_VAR_LATEST_REVOCATIONS "shim,2\ngrub,2\n" + #define SBAT_VAR_LATEST \ + SBAT_VAR_SIG SBAT_VAR_VERSION SBAT_VAR_LATEST_DATE "\n" \ + SBAT_VAR_LATEST_REVOCATIONS +-- +2.35.1 + diff --git a/0006-Also-avoid-CVE-2022-28737-in-verify_image.patch b/0006-Also-avoid-CVE-2022-28737-in-verify_image.patch new file mode 100644 index 0000000..210bef6 --- /dev/null +++ b/0006-Also-avoid-CVE-2022-28737-in-verify_image.patch @@ -0,0 +1,84 @@ +From 159151b6649008793d6204a34d7b9c41221fb4b0 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 3 May 2022 17:05:20 -0400 +Subject: [PATCH 6/6] Also avoid CVE-2022-28737 in verify_image() + +PR 446 ("Add verify_image") duplicates some of the code affected by +Chris Coulson's defense in depth patch against CVE-2022-28737 ("pe: +Perform image verification earlier when loading grub"). + +This patch makes the same change to the new function. + +Signed-off-by: Peter Jones +--- + pe.c | 46 +++++++++++++++++++++++++++------------------- + 1 file changed, 27 insertions(+), 19 deletions(-) + +diff --git a/pe.c b/pe.c +index 1d120f2d78d..ba3e2bbc444 100644 +--- a/pe.c ++++ b/pe.c +@@ -1038,26 +1038,9 @@ EFI_STATUS verify_image(void *data, unsigned int datasize, + } + + /* +- * We only need to verify the binary if we're in secure mode ++ * Perform the image verification before we start copying data around ++ * in order to load it. + */ +- efi_status = generate_hash(data, datasize, context, sha256hash, +- sha1hash); +- if (EFI_ERROR(efi_status)) +- return efi_status; +- +- /* Measure the binary into the TPM */ +-#ifdef REQUIRE_TPM +- efi_status = +-#endif +- tpm_log_pe((EFI_PHYSICAL_ADDRESS)(UINTN)data, datasize, +- (EFI_PHYSICAL_ADDRESS)(UINTN)context->ImageAddress, +- li->FilePath, sha1hash, 4); +-#ifdef REQUIRE_TPM +- if (efi_status != EFI_SUCCESS) { +- return efi_status; +- } +-#endif +- + if (secure_mode()) { + efi_status = verify_buffer(data, datasize, + context, sha256hash, sha1hash); +@@ -1071,6 +1054,31 @@ EFI_STATUS verify_image(void *data, unsigned int datasize, + console_print(L"Verification succeeded\n"); + } + ++ /* ++ * Calculate the hash for the TPM measurement. ++ * XXX: We're computing these twice in secure boot mode when the ++ * buffers already contain the previously computed hashes. Also, ++ * this is only useful for the TPM1.2 case. We should try to fix ++ * this in a follow-up. ++ */ ++ efi_status = generate_hash(data, datasize, context, sha256hash, ++ sha1hash); ++ if (EFI_ERROR(efi_status)) ++ return efi_status; ++ ++ /* Measure the binary into the TPM */ ++#ifdef REQUIRE_TPM ++ efi_status = ++#endif ++ tpm_log_pe((EFI_PHYSICAL_ADDRESS)(UINTN)data, datasize, ++ (EFI_PHYSICAL_ADDRESS)(UINTN)context->ImageAddress, ++ li->FilePath, sha1hash, 4); ++#ifdef REQUIRE_TPM ++ if (efi_status != EFI_SUCCESS) { ++ return efi_status; ++ } ++#endif ++ + return EFI_SUCCESS; + } + +-- +2.35.1 + diff --git a/shim-unsigned-x64.spec b/shim-unsigned-x64.spec index 26331e2..fb41cc7 100644 --- a/shim-unsigned-x64.spec +++ b/shim-unsigned-x64.spec @@ -19,7 +19,7 @@ %global dbxfile %{nil} Name: shim-unsigned-%{efiarch} -Version: 15.5 +Version: 15.6~rc1 Release: 1.el9 Summary: First-stage UEFI bootloader ExclusiveArch: x86_64 @@ -34,6 +34,13 @@ Source3: sbat.redhat.csv Source100: shim-find-debuginfo.sh +Patch0001: 0001-SBAT-Policy-latest-should-be-a-one-shot.patch +Patch0002: 0002-pe-Fix-a-buffer-overflow-when-SizeOfRawData-VirtualS.patch +Patch0003: 0003-pe-Perform-image-verification-earlier-when-loading-g.patch +Patch0004: 0004-Update-advertised-sbat-generation-number-for-shim.patch +Patch0005: 0005-Update-SBAT-generation-requirements-for-05-24-22.patch +Patch0006: 0006-Also-avoid-CVE-2022-28737-in-verify_image.patch + BuildRequires: gcc make BuildRequires: elfutils-libelf-devel BuildRequires: git openssl-devel openssl @@ -92,7 +99,7 @@ BuildArch: noarch %debug_desc %prep -%autosetup -S git -n shim-%{version} +%autosetup -S git_am -n shim-%{version} git config --unset user.email git config --unset user.name mkdir build-%{efiarch} @@ -155,6 +162,10 @@ cd .. %files debugsource -f build-%{efiarch}/debugsource.list %changelog +* Tue May 24 2022 Peter Jones - 15.6~rc1-1.el9 +- Update to shim-15.6~rc1 + Resolves: CVE-2022-28737 + * Wed Mar 09 2022 Peter Jones - 15.5-1 - Update to shim-15.5 Related: rhbz#1932057 diff --git a/sources b/sources index fe04942..fdc9e71 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (shim-15.5.tar.bz2) = 91fbda1ef0b4ea36538b57179488169f37eb8522d8dbbbf2eeb40708bc013073b4454b4205a957df13e1e15b9151c6013a8292691f9e3ab28ba7d0935fcc4fab +SHA512 (shim-15.6~rc1.tar.bz2) = e654f04fcf171c69fd3cf0396c246cbdb43fee8a865ebe14a9ed75f7ddef79d14cb7c58a382f7407ec34508131d58c700f4ef8bab2203ee7ec06d9a326a4c950