diff --git a/0455-tpm-Disable-the-tpm-verifier-if-the-TPM-device-is-no.patch b/0455-tpm-Disable-the-tpm-verifier-if-the-TPM-device-is-no.patch new file mode 100644 index 0000000..47d626f --- /dev/null +++ b/0455-tpm-Disable-the-tpm-verifier-if-the-TPM-device-is-no.patch @@ -0,0 +1,156 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Wed, 22 Mar 2023 12:25:43 +0800 +Subject: [PATCH] tpm: Disable the tpm verifier if the TPM device is not + present + +When the tpm module is loaded, the verifier reads entire file into +memory, measures it and uses verified content as a backing buffer for +file accesses. However, this process may result in high memory +utilization for file operations, sometimes causing a system to run out +of memory which may finally lead to boot failure. To address this issue, +among others, the commit 887f98f0d (mm: Allow dynamically requesting +additional memory regions) have optimized memory management by +dynamically allocating heap space to maximize memory usage and reduce +threat of memory exhaustion. But in some cases problems may still arise, +e.g., when large ISO images are mounted using loopback or when dealing +with embedded systems with limited memory resources. + +Unfortunately current implementation of the tpm module doesn't allow +elimination of the back buffer once it is loaded. Even if the TPM device +is not present or it has been explicitly disabled. This may unnecessary +allocate a lot memory. To solve this issue, a patch has been developed +to detect the TPM status at module load and skip verifier registration +if the device is missing or deactivated. This prevents allocation of +memory for the back buffer, avoiding wasting memory when no real measure +boot functionality is performed. Disabling the TPM device in the system +can reduce memory usage in the GRUB. It is useful in scenarios where +high memory utilization is a concern and measurements of loaded +artifacts are not necessary. + +Signed-off-by: Michael Chang +Signed-off-by: Stefan Berger +Reviewed-by: Daniel Kiper +(cherry picked from commit 30708dfe3bebd62a5487437554da8a24253f519f) +--- + grub-core/commands/efi/tpm.c | 37 +++++++++++++++++++++++++++++++++++ + grub-core/commands/ieee1275/ibmvtpm.c | 20 +++++++++---------- + grub-core/commands/tpm.c | 10 ++++++++++ + include/grub/tpm.h | 1 + + 4 files changed, 58 insertions(+), 10 deletions(-) + +diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c +index ae09c1bf8bc5..e1f343fea3ff 100644 +--- a/grub-core/commands/efi/tpm.c ++++ b/grub-core/commands/efi/tpm.c +@@ -287,3 +287,40 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, + else + return grub_tpm2_log_event (tpm_handle, buf, size, pcr, description); + } ++ ++int ++grub_tpm_present (void) ++{ ++ grub_efi_handle_t tpm_handle; ++ grub_efi_uint8_t protocol_version; ++ ++ if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) ++ return 0; ++ ++ if (protocol_version == 1) ++ { ++ grub_efi_tpm_protocol_t *tpm; ++ ++ tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid, ++ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); ++ if (!tpm) ++ { ++ grub_dprintf ("tpm", "Cannot open TPM protocol\n"); ++ return 0; ++ } ++ return grub_tpm1_present (tpm); ++ } ++ else ++ { ++ grub_efi_tpm2_protocol_t *tpm; ++ ++ tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, ++ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); ++ if (!tpm) ++ { ++ grub_dprintf ("tpm", "Cannot open TPM protocol\n"); ++ return 0; ++ } ++ return grub_tpm2_present (tpm); ++ } ++} +diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c +index 239942d27e55..a6fee5c516dc 100644 +--- a/grub-core/commands/ieee1275/ibmvtpm.c ++++ b/grub-core/commands/ieee1275/ibmvtpm.c +@@ -135,16 +135,6 @@ grub_err_t + grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, + const char *description) + { +- /* +- * Call tpm_init() 'late' rather than from GRUB_MOD_INIT() so that device nodes +- * can be found. +- */ +- grub_err_t err = tpm_init (); +- +- /* Absence of a TPM isn't a failure. */ +- if (err != GRUB_ERR_NONE) +- return GRUB_ERR_NONE; +- + grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n", + pcr, size, description); + +@@ -153,3 +143,13 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, + + return GRUB_ERR_NONE; + } ++ ++int ++grub_tpm_present (void) ++{ ++ /* ++ * Call tpm_init() "late" rather than from GRUB_MOD_INIT() so that device nodes ++ * can be found. ++ */ ++ return tpm_init() == GRUB_ERR_NONE; ++} +diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm.c +index e287d042e6b4..5839053d3df8 100644 +--- a/grub-core/commands/tpm.c ++++ b/grub-core/commands/tpm.c +@@ -86,10 +86,20 @@ struct grub_file_verifier grub_tpm_verifier = { + + GRUB_MOD_INIT (tpm) + { ++ /* ++ * Even though this now calls ibmvtpm's grub_tpm_present() from GRUB_MOD_INIT(), ++ * it does seem to call it late enough in the initialization sequence so ++ * that whatever discovered "device nodes" before this GRUB_MOD_INIT() is ++ * called, enables the ibmvtpm driver to see the device nodes. ++ */ ++ if (!grub_tpm_present()) ++ return; + grub_verifier_register (&grub_tpm_verifier); + } + + GRUB_MOD_FINI (tpm) + { ++ if (!grub_tpm_present()) ++ return; + grub_verifier_unregister (&grub_tpm_verifier); + } +diff --git a/include/grub/tpm.h b/include/grub/tpm.h +index 5c285cbc5256..c19fcbd0a60d 100644 +--- a/include/grub/tpm.h ++++ b/include/grub/tpm.h +@@ -36,4 +36,5 @@ + + grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size, + grub_uint8_t pcr, const char *description); ++int grub_tpm_present (void); + #endif diff --git a/0456-powerpc-increase-MIN-RMA-size-for-CAS-negotiation.patch b/0456-powerpc-increase-MIN-RMA-size-for-CAS-negotiation.patch new file mode 100644 index 0000000..1e7dc90 --- /dev/null +++ b/0456-powerpc-increase-MIN-RMA-size-for-CAS-negotiation.patch @@ -0,0 +1,117 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Avnish Chouhan +Date: Thu, 13 Mar 2025 19:45:50 +0530 +Subject: [PATCH] powerpc: increase MIN RMA size for CAS negotiation + +Change RMA size from 512 MB to 768 MB which will result +in more memory at boot time for PowerPC. When vTPM, Secure Boot or +FADump are enabled on PowerPC, the 512 MB RMA memory is not sufficient for +booting. With this 512 MB RMA, GRUB2 runs out of memory and fails to +boot the machine. Sometimes even usage of CDROM requires more memory +for installation and along with the options mentioned above exhausts +the boot memory which results in boot failures. Increasing the RMA size +will resolves multiple out of memory issues observed in PowerPC. + +Failure details (GRUB2 debugs): + + kern/ieee1275/init.c:550: mm requested region of size 8513000, flags 1 + kern/ieee1275/init.c:563: Cannot satisfy allocation and retain minimum runtime space + kern/ieee1275/init.c:550: mm requested region of size 8513000, flags 0 + kern/ieee1275/init.c:563: Cannot satisfy allocation and retain minimum runtime space + kern/file.c:215: Closing `/ppc/ppc64/initrd.img' ... + kern/disk.c:297: Closing `ieee1275//vdevice/v-scsi@30000067/disk@8300000000000000'... + kern/disk.c:311: Closing `ieee1275//vdevice/v-scsi@30000067/disk@8300000000000000' succeeded. + kern/file.c:225: Closing `/ppc/ppc64/initrd.img' failed with 3. + kern/file.c:148: Opening `/ppc/ppc64/initrd.img' succeeded. + error: ../../grub-core/kern/mm.c:552:out of memory. + +Signed-off-by: Avnish Chouhan +--- + grub-core/kern/ieee1275/init.c | 51 +++++++++++++++++++++++++++++++++++++----- + 1 file changed, 46 insertions(+), 5 deletions(-) + +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c +index 4ec6598cfbb8..bb791f80f41c 100644 +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -737,7 +737,7 @@ struct cas_vector + + /* + * Call ibm,client-architecture-support to try to get more RMA. +- * We ask for 512MB which should be enough to verify a distro kernel. ++ * We ask for 768MB which should be enough to verify a distro kernel. + * We ignore most errors: if we don't succeed we'll proceed with whatever + * memory we have. + */ +@@ -809,7 +809,7 @@ grub_ieee1275_ibm_cas (void) + .vec1 = 0x80, /* ignore */ + .vec2_size = 1 + sizeof (struct option_vector2) - 2, + .vec2 = { +- 0, 0, -1, -1, -1, -1, -1, 512, -1, 0, 48 ++ 0, 0, -1, -1, -1, -1, -1, 768, -1, 0, 48 + }, + .vec3_size = 2 - 1, + .vec3 = 0x00e0, /* ask for FP + VMX + DFP but don't halt if unsatisfied */ +@@ -846,6 +846,10 @@ grub_claim_heap (void) + { + grub_err_t err; + grub_uint32_t total = HEAP_MAX_SIZE; ++#if defined(__powerpc__) ++ grub_uint32_t ibm_ca_support_reboot = 0; ++ grub_ssize_t actual; ++#endif + + err = grub_ieee1275_total_mem (&rmo_top); + +@@ -858,11 +862,48 @@ grub_claim_heap (void) + grub_mm_add_region_fn = grub_ieee1275_mm_add_region; + + #if defined(__powerpc__) ++ /* Check if it's a CAS reboot with below property. If so, we will skip CAS call */ ++ if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, ++ "ibm,client-architecture-support-reboot", ++ &ibm_ca_support_reboot, ++ sizeof (ibm_ca_support_reboot), ++ &actual) >= 0) ++ grub_dprintf ("ieee1275", "ibm,client-architecture-support-reboot: %" PRIuGRUB_UINT32_T "\n", ++ ibm_ca_support_reboot); ++ + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY)) + { +- /* if we have an error, don't call CAS, just hope for the best */ +- if (err == GRUB_ERR_NONE && rmo_top < (512 * 1024 * 1024)) +- grub_ieee1275_ibm_cas (); ++ /* ++ * If we have an error, don't call CAS. Just hope for the best. ++ * Along with the above, if the rmo_top is 512 MB or above. We ++ * will skip the CAS call. However, if we call CAS, the rmo_top ++ * will be set to 768 MB via CAS Vector2. But we need to call ++ * CAS with "rmo_top < 512 MB" to avoid the issue on the older ++ * Linux kernel, which still uses rmo_top as 512 MB. If we call ++ * CAS with a condition "rmo_top < 768 MB", it will result in an ++ * issue due to the IBM CAS reboot feature and we won't be able ++ * to boot the newer kernel. Whenever a reboot is detected as ++ * the CAS reboot by GRUB. It will boot the machine with the ++ * last booted kernel by reading the variable "boot-last-label" ++ * which has the info related to the last boot and it's specific ++ * to IBM PowerPC. Due to this, the machine will boot with the ++ * last booted kernel which has rmo_top as 512 MB. Also, if the ++ * reboot is detected as a CAS reboot, the GRUB will skip the CAS ++ * call. As the CAS has already been called earlier, so it is ++ * not required to call CAS even if the other conditions are met. ++ * This condition will also prevent a scenario where the machine ++ * get stuck in the CAS reboot loop while booting. A machine with ++ * an older kernel, having option_vector2 MIN_RMA as 512 MB in ++ * Linux prom_init.c and GRUB uses "rmo_top < 768 MB" condition ++ * for calling CAS. Due to their respective conditions, linux ++ * CAS and GRUB CAS will keep doing the CAS calls and change ++ * the MIN_RMA from 768(changed by GRUB) to 512(changed by Linux) ++ * to 768(changed by GRUB) to 512(changed by Linux) and so on, ++ * and the machine will stuck in this CAS reboot loop forever. ++ * IBM PAPR : https://openpower.foundation/specifications/linuxonpower/ ++ */ ++ if (!ibm_ca_support_reboot && err == GRUB_ERR_NONE && rmo_top < (512 * 1024 * 1024)) ++ grub_ieee1275_ibm_cas (); + } + #endif + diff --git a/grub.patches b/grub.patches index 9b8c8e7..a55001c 100644 --- a/grub.patches +++ b/grub.patches @@ -451,3 +451,5 @@ Patch0451: 0451-types-Make-bool-generally-available.patch Patch0452: 0452-include-grub-types.h-Add-PRI-GRUB_OFFSET-and-PRI-GRU.patch Patch0453: 0453-fs-xfs-Fix-issues-found-while-fuzzing-the-XFS-filesy.patch Patch0454: 0454-fs-ext2-Rework-out-of-bounds-read-for-inline-and-ext.patch +Patch0455: 0455-tpm-Disable-the-tpm-verifier-if-the-TPM-device-is-no.patch +Patch0456: 0456-powerpc-increase-MIN-RMA-size-for-CAS-negotiation.patch diff --git a/grub2.spec b/grub2.spec index 3ca0d40..b8f45f7 100644 --- a/grub2.spec +++ b/grub2.spec @@ -16,7 +16,7 @@ Name: grub2 Epoch: 1 Version: 2.06 -Release: 98%{?dist} +Release: 99%{?dist} Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -547,6 +547,12 @@ mv ${EFI_HOME}/grub.cfg.stb ${EFI_HOME}/grub.cfg %endif %changelog +* Mon Mar 17 2025 Nicolas Frayer 2.06-99 +- Added the following 2 commits to optimize memory consumption +- tpm: Disable the tpm verifier if the TPM device is not present +- powerpc: increase MIN RMA size for CAS negotiation +- Resolves: #RHEL-76558 + * Mon Mar 10 2025 Leo Sandoval 2.06-98 - Remove 'fs/ntfs: Implement attribute verification' patch - Related: RHEL-83117