From 9de60d80a53b57c0562dcc4b26e8809114efc93b0ca5a7c3d3b9ce447c68decb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Schr=C3=B6ter?= Date: Thu, 20 Feb 2025 09:30:07 +0100 Subject: [PATCH] Sync from SUSE:SLFO:Main grub2 revision 77044287ba2f00209f12a86c4e01643b --- 0001-misc-Implement-grub_strlcpy.patch | 68 +++ ...ase-MIN-RMA-size-for-CAS-negotiation.patch | 102 ++++ ...tication-after-tpm-unlock-for-CLI-ac.patch | 71 +-- 0002-fs-ufs-Fix-a-heap-OOB-write.patch | 34 ++ ...Fix-stack-OOB-write-with-grub_strcpy.patch | 34 ++ ...ger-overflow-leads-to-heap-OOB-write.patch | 92 ++++ ...plus-Set-a-grub_errno-if-mount-fails.patch | 38 ++ 0006-kern-file-Ensure-file-data-is-set.patch | 35 ++ ...lement-filesystem-reference-counting.patch | 443 ++++++++++++++++++ ...write-in-grub_net_search_config_file.patch | 83 ++++ ...eg-Do-not-permit-duplicate-SOF0-mark.patch | 36 ++ ...-Missing-check-for-failed-allocation.patch | 37 ++ ...egister-the-check_signatures-hooks-o.patch | 34 ++ ...ove-variables-hooks-on-module-unload.patch | 40 ++ ...ove-variables-hooks-on-module-unload.patch | 37 ++ ...overflow-leads-to-heap-OOB-write-or-.patch | 39 ++ ...ger-overflow-leads-to-heap-OOB-write.patch | 56 +++ ...x-an-integer-overflow-when-supplying.patch | 72 +++ ...-Block-the-dump-command-in-lockdown-.patch | 37 ++ 0018-fs-bfs-Disable-under-lockdown.patch | 55 +++ ...able-many-filesystems-under-lockdown.patch | 394 ++++++++++++++++ ...lows-when-allocating-memory-for-arra.patch | 85 ++++ grub2.changes | 58 +++ grub2.spec | 25 +- 24 files changed, 1970 insertions(+), 35 deletions(-) create mode 100644 0001-misc-Implement-grub_strlcpy.patch create mode 100644 0001-powerpc-increase-MIN-RMA-size-for-CAS-negotiation.patch create mode 100644 0002-fs-ufs-Fix-a-heap-OOB-write.patch create mode 100644 0003-fs-hfs-Fix-stack-OOB-write-with-grub_strcpy.patch create mode 100644 0004-fs-tar-Integer-overflow-leads-to-heap-OOB-write.patch create mode 100644 0005-fs-hfsplus-Set-a-grub_errno-if-mount-fails.patch create mode 100644 0006-kern-file-Ensure-file-data-is-set.patch create mode 100644 0007-kern-file-Implement-filesystem-reference-counting.patch create mode 100644 0008-net-Fix-OOB-write-in-grub_net_search_config_file.patch create mode 100644 0009-video-readers-jpeg-Do-not-permit-duplicate-SOF0-mark.patch create mode 100644 0010-commands-extcmd-Missing-check-for-failed-allocation.patch create mode 100644 0011-commands-pgp-Unregister-the-check_signatures-hooks-o.patch create mode 100644 0012-normal-Remove-variables-hooks-on-module-unload.patch create mode 100644 0013-gettext-Remove-variables-hooks-on-module-unload.patch create mode 100644 0014-gettext-Integer-overflow-leads-to-heap-OOB-write-or-.patch create mode 100644 0015-gettext-Integer-overflow-leads-to-heap-OOB-write.patch create mode 100644 0016-commands-read-Fix-an-integer-overflow-when-supplying.patch create mode 100644 0017-commands-minicmd-Block-the-dump-command-in-lockdown-.patch create mode 100644 0018-fs-bfs-Disable-under-lockdown.patch create mode 100644 0019-fs-Disable-many-filesystems-under-lockdown.patch create mode 100644 0020-fs-Prevent-overflows-when-allocating-memory-for-arra.patch diff --git a/0001-misc-Implement-grub_strlcpy.patch b/0001-misc-Implement-grub_strlcpy.patch new file mode 100644 index 0000000..d2b37aa --- /dev/null +++ b/0001-misc-Implement-grub_strlcpy.patch @@ -0,0 +1,68 @@ +From f0a61161f74f9855af84778261338224d926a61f Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Sat, 15 Jun 2024 02:33:08 +0100 +Subject: [PATCH 01/20] misc: Implement grub_strlcpy() + +grub_strlcpy() acts the same way as strlcpy() does on most *NIX, +returning the length of src and ensuring dest is always NUL +terminated except when size is 0. + +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + include/grub/misc.h | 39 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 39 insertions(+) + +diff --git a/include/grub/misc.h b/include/grub/misc.h +index 6e94d18f5a..e087e7b3e8 100644 +--- a/include/grub/misc.h ++++ b/include/grub/misc.h +@@ -64,6 +64,45 @@ grub_stpcpy (char *dest, const char *src) + return d - 1; + } + ++static inline grub_size_t ++grub_strlcpy (char *dest, const char *src, grub_size_t size) ++{ ++ char *d = dest; ++ grub_size_t res = 0; ++ /* ++ * We do not subtract one from size here to avoid dealing with underflowing ++ * the value, which is why to_copy is always checked to be greater than one ++ * throughout this function. ++ */ ++ grub_size_t to_copy = size; ++ ++ /* Copy size - 1 bytes to dest. */ ++ if (to_copy > 1) ++ while ((*d++ = *src++) != '\0' && ++res && --to_copy > 1) ++ ; ++ ++ /* ++ * NUL terminate if size != 0. The previous step may have copied a NUL byte ++ * if it reached the end of the string, but we know dest[size - 1] must always ++ * be a NUL byte. ++ */ ++ if (size != 0) ++ dest[size - 1] = '\0'; ++ ++ /* If there is still space in dest, but are here, we reached the end of src. */ ++ if (to_copy > 1) ++ return res; ++ ++ /* ++ * If we haven't reached the end of the string, iterate through to determine ++ * the strings total length. ++ */ ++ while (*src++ != '\0' && ++res) ++ ; ++ ++ return res; ++} ++ + /* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ + static inline void * + grub_memcpy (void *dest, const void *src, grub_size_t n) +-- +2.48.1 + diff --git a/0001-powerpc-increase-MIN-RMA-size-for-CAS-negotiation.patch b/0001-powerpc-increase-MIN-RMA-size-for-CAS-negotiation.patch new file mode 100644 index 0000000..013b7aa --- /dev/null +++ b/0001-powerpc-increase-MIN-RMA-size-for-CAS-negotiation.patch @@ -0,0 +1,102 @@ +From 68a2663cc316d55c2670a639c8a4a2a43ffdb141 Mon Sep 17 00:00:00 2001 +From: Avnish Chouhan +Date: Wed, 15 Jan 2025 17:46:05 +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 PowerPC LPAR use/uses vTPM, +Secure Boot or FADump, the 512 MB RMA memory is not sufficient for +booting. With this 512 MB RMA, GRUB2 run out of memory and unable to +load the necessary. Sometimes even usage of CDROM which requires more +memory for installation along with the options mentioned above troubles +the boot memory and result 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 +Link: https://lore.kernel.org/r/20250115121605.56049-1-avnish@linux.ibm.com +--- + grub-core/kern/ieee1275/init.c | 33 +++++++++++++++++++++++++++++---- + 1 file changed, 29 insertions(+), 4 deletions(-) + +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c +index 8e08e5dd5c..e0634603ef 100644 +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -855,7 +855,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 */ +@@ -892,6 +892,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; ++ grub_ssize_t actual; ++#endif + + err = grub_ieee1275_total_mem (&rmo_top); + +@@ -904,11 +908,32 @@ 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 */ ++ ibm_ca_support_reboot = 0; ++ 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: %u\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 or the reboot is detected as CAS reboot, ++ * 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. Though if we call CAS, the rmo_top will ++ * be set to 768 MB via CAS Vector2. This condition is required to avoid the ++ * issue where the older Linux kernels are still using rmo_top as 512 MB. ++ * Calling CAS when rmo_top is less then 768 MB will result in a issue ++ * where we won't be able to boot to a newer kernel and continue to ++ * boot with older kernel having rmo_top as 512 MB. ++ */ ++ if (!ibm_ca_support_reboot && err == GRUB_ERR_NONE ++ && rmo_top < (512 * 1024 * 1024)) ++ grub_ieee1275_ibm_cas (); + } + #endif + +-- +2.48.1 + diff --git a/0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch b/0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch index 350d92e..38cc410 100644 --- a/0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch +++ b/0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch @@ -1,15 +1,15 @@ -From af8b106667aa2ca7a7613e10d8746959e182f8f1 Mon Sep 17 00:00:00 2001 +From 0ed98269c5631c4d094b2cee81ce385687803730 Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Thu, 29 Aug 2024 13:27:30 +0800 Subject: [PATCH 2/2] Requiring authentication after tpm unlock for CLI access -GRUB may use TPM to verify the integrity of boot components, and the +The GRUB may use TPM to verify the integrity of boot components and the result can determine whether a previously sealed key can be released. If everything checks out, showing nothing has been tampered with, the key -is released, and grub unlocks the encrypted root partition for the next +is released and GRUB unlocks the encrypted root partition for the next stage of booting. -However, the liberal command line interface (CLI) can be misused by +However, the liberal Command Line Interface (CLI) can be misused by anyone in this case to access files in the encrypted partition one way or another. Despite efforts to keep the CLI secure by preventing utility command output from leaking file content, many techniques in the wild @@ -20,25 +20,26 @@ where a hack could be applied. Therefore, to mitigate potential misuse of the CLI after the root device has been successfully unlocked via TPM, the user should be required to authenticate using the LUKS password. This added layer of security -ensures that only authorized users can access the CLI, reducing the risk +ensures that only authorized users can access the CLI reducing the risk of exploitation or unauthorized access to the encrypted partition. Fixes: CVE-2024-49504 Signed-off-by: Michael Chang +Reviewed-by: Daniel Kiper --- - grub-core/disk/cryptodisk.c | 80 +++++++++++++++++++++++++++++++++++ - grub-core/kern/main.c | 12 ++++++ + grub-core/disk/cryptodisk.c | 84 +++++++++++++++++++++++++++++++++++ + grub-core/kern/main.c | 12 +++++ grub-core/normal/auth.c | 30 +++++++++++++ grub-core/normal/main.c | 4 ++ grub-core/normal/menu_entry.c | 4 ++ include/grub/auth.h | 1 + include/grub/cryptodisk.h | 3 ++ include/grub/misc.h | 2 + - 8 files changed, 136 insertions(+) + 8 files changed, 140 insertions(+) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c -index babc94868..77bc782fd 100644 +index babc94868d..21bf22ead1 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -1188,6 +1188,7 @@ grub_cryptodisk_scan_device_real (const char *name, @@ -49,7 +50,7 @@ index babc94868..77bc782fd 100644 #endif goto cleanup; } -@@ -1706,6 +1707,85 @@ luks_script_get (grub_size_t *sz) +@@ -1706,6 +1707,89 @@ luks_script_get (grub_size_t *sz) return ret; } @@ -74,25 +75,30 @@ index babc94868..77bc782fd 100644 + source = grub_disk_open (cr_dev->source); + + if (source == NULL) -+ goto error_out; ++ { ++ ret = grub_errno; ++ goto error_out; ++ } + + FOR_CRYPTODISK_DEVS (cr) + { + dev = cr->scan (source, &cargs); + if (grub_errno) -+ goto error_out; -+ if (!dev) ++ { ++ ret = grub_errno; ++ goto error_out; ++ } ++ if (dev == NULL) + continue; + break; + } + + if (dev == NULL) + { -+ grub_error (GRUB_ERR_BAD_MODULE, -+ "no cryptodisk module can handle this device"); ++ ret = grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device"); + goto error_out; + } -+ ++ + part = grub_partition_get_name (source->partition); + grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, + source->partition != NULL ? "," : "", @@ -101,22 +107,22 @@ index babc94868..77bc782fd 100644 + + cargs.key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE); + if (cargs.key_data == NULL) -+ goto error_out; ++ { ++ ret = grub_errno; ++ goto error_out; ++ } + + if (!grub_password_get ((char *) cargs.key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE)) + { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied"); ++ ret = grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied"); + goto error_out; + } + cargs.key_len = grub_strlen ((char *) cargs.key_data); + ret = cr->recover_key (source, dev, &cargs); -+ if (ret != GRUB_ERR_NONE) -+ goto error_out; + + error_out: -+ if (source) -+ grub_disk_close (source); -+ if (dev) ++ grub_disk_close (source); ++ if (dev != NULL) + cryptodisk_close (dev); + if (cargs.key_data) + { @@ -124,8 +130,7 @@ index babc94868..77bc782fd 100644 + grub_free (cargs.key_data); + } + -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; ++ return ret; + } + + return GRUB_ERR_NONE; @@ -136,7 +141,7 @@ index babc94868..77bc782fd 100644 { .name = "luks_script", diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c -index 07b6940d2..ef3b3756d 100644 +index 07b6940d2e..ef3b3756de 100644 --- a/grub-core/kern/main.c +++ b/grub-core/kern/main.c @@ -37,6 +37,7 @@ @@ -166,7 +171,7 @@ index 07b6940d2..ef3b3756d 100644 check_is_cli_disabled (void) { diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c -index d94020186..2931ba604 100644 +index d940201866..2931ba604a 100644 --- a/grub-core/normal/auth.c +++ b/grub-core/normal/auth.c @@ -25,6 +25,10 @@ @@ -214,7 +219,7 @@ index d94020186..2931ba604 100644 grub_auth_check_authentication (const char *userlist) { diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 8e58ced67..b08fd6977 100644 +index 8e58ced679..b08fd6977d 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -560,9 +560,13 @@ grub_cmdline_run (int nested, int force_auth) @@ -232,7 +237,7 @@ index 8e58ced67..b08fd6977 100644 return; } diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c -index e5ba91ea4..06682a396 100644 +index e5ba91ea4d..06682a396d 100644 --- a/grub-core/normal/menu_entry.c +++ b/grub-core/normal/menu_entry.c @@ -1256,9 +1256,13 @@ grub_menu_entry_run (grub_menu_entry_t entry) @@ -250,7 +255,7 @@ index e5ba91ea4..06682a396 100644 return; } diff --git a/include/grub/auth.h b/include/grub/auth.h -index 747334451..21d5190f0 100644 +index 7473344517..21d5190f04 100644 --- a/include/grub/auth.h +++ b/include/grub/auth.h @@ -33,5 +33,6 @@ grub_err_t grub_auth_unregister_authentication (const char *user); @@ -261,7 +266,7 @@ index 747334451..21d5190f0 100644 #endif /* ! GRUB_AUTH_HEADER */ diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h -index 0b41e249e..b3291519b 100644 +index 0b41e249e8..b3291519b1 100644 --- a/include/grub/cryptodisk.h +++ b/include/grub/cryptodisk.h @@ -203,4 +203,7 @@ grub_util_get_geli_uuid (const char *dev); @@ -273,7 +278,7 @@ index 0b41e249e..b3291519b 100644 +#endif #endif diff --git a/include/grub/misc.h b/include/grub/misc.h -index 1578f36c3..6e94d18f5 100644 +index 1578f36c3c..6e94d18f5a 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -392,6 +392,8 @@ grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, @@ -286,5 +291,5 @@ index 1578f36c3..6e94d18f5 100644 /* Must match softdiv group in gentpl.py. */ #if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \ -- -2.47.0 +2.47.1 diff --git a/0002-fs-ufs-Fix-a-heap-OOB-write.patch b/0002-fs-ufs-Fix-a-heap-OOB-write.patch new file mode 100644 index 0000000..14471d5 --- /dev/null +++ b/0002-fs-ufs-Fix-a-heap-OOB-write.patch @@ -0,0 +1,34 @@ +From daec67a7ea73b859e1e0b6a4e9122157c7525676 Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Sun, 12 May 2024 02:03:33 +0100 +Subject: [PATCH 02/20] fs/ufs: Fix a heap OOB write + +grub_strcpy() was used to copy a symlink name from the filesystem +image to a heap allocated buffer. This led to a OOB write to adjacent +heap allocations. Fix by using grub_strlcpy(). + +Fixes: CVE-2024-45781 + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/fs/ufs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c +index a354c92d93..01235101b4 100644 +--- a/grub-core/fs/ufs.c ++++ b/grub-core/fs/ufs.c +@@ -463,7 +463,7 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino) + /* Check against zero is paylindromic, no need to swap. */ + if (data->inode.nblocks == 0 + && INODE_SIZE (data) <= sizeof (data->inode.symlink)) +- grub_strcpy (symlink, (char *) data->inode.symlink); ++ grub_strlcpy (symlink, (char *) data->inode.symlink, sz); + else + { + if (grub_ufs_read_file (data, 0, 0, 0, sz, symlink) < 0) +-- +2.48.1 + diff --git a/0003-fs-hfs-Fix-stack-OOB-write-with-grub_strcpy.patch b/0003-fs-hfs-Fix-stack-OOB-write-with-grub_strcpy.patch new file mode 100644 index 0000000..723d74b --- /dev/null +++ b/0003-fs-hfs-Fix-stack-OOB-write-with-grub_strcpy.patch @@ -0,0 +1,34 @@ +From 96f51e8fb8daf43da636f6475827d697829fdb8b Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Sun, 12 May 2024 02:48:33 +0100 +Subject: [PATCH 03/20] fs/hfs: Fix stack OOB write with grub_strcpy() + +Replaced with grub_strlcpy(). + +Fixes: CVE-2024-45782 +Fixes: CVE-2024-56737 +Fixes: https://savannah.gnu.org/bugs/?66599 + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/fs/hfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c +index 91dc0e69c3..920112b03e 100644 +--- a/grub-core/fs/hfs.c ++++ b/grub-core/fs/hfs.c +@@ -379,7 +379,7 @@ grub_hfs_mount (grub_disk_t disk) + volume name. */ + key.parent_dir = grub_cpu_to_be32_compile_time (1); + key.strlen = data->sblock.volname[0]; +- grub_strcpy ((char *) key.str, (char *) (data->sblock.volname + 1)); ++ grub_strlcpy ((char *) key.str, (char *) (data->sblock.volname + 1), sizeof (key.str)); + + if (grub_hfs_find_node (data, (char *) &key, data->cat_root, + 0, (char *) &dir, sizeof (dir)) == 0) +-- +2.48.1 + diff --git a/0004-fs-tar-Integer-overflow-leads-to-heap-OOB-write.patch b/0004-fs-tar-Integer-overflow-leads-to-heap-OOB-write.patch new file mode 100644 index 0000000..a5c987e --- /dev/null +++ b/0004-fs-tar-Integer-overflow-leads-to-heap-OOB-write.patch @@ -0,0 +1,92 @@ +From 8f99c43384b9122eedeab1411ab5076ca5878ef9 Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Fri, 22 Nov 2024 06:27:58 +0000 +Subject: [PATCH 04/20] fs/tar: Integer overflow leads to heap OOB write + +Both namesize and linksize are derived from hd.size, a 12-digit octal +number parsed by read_number(). Later direct arithmetic calculation like +"namesize + 1" and "linksize + 1" may exceed the maximum value of +grub_size_t leading to heap OOB write. This patch fixes the issue by +using grub_add() and checking for an overflow. + +Fixes: CVE-2024-45780 + +Reported-by: Nils Langius +Signed-off-by: Lidong Chen +Reviewed-by: Daniel Kiper +Reviewed-by: Alec Brown +--- + grub-core/fs/tar.c | 23 ++++++++++++++++++----- + 1 file changed, 18 insertions(+), 5 deletions(-) + +diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c +index c551ed6b52..a9e39b0eb6 100644 +--- a/grub-core/fs/tar.c ++++ b/grub-core/fs/tar.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -76,6 +77,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, + { + struct head hd; + int reread = 0, have_longname = 0, have_longlink = 0; ++ grub_size_t sz; + + data->hofs = data->next_hofs; + +@@ -97,7 +99,11 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, + { + grub_err_t err; + grub_size_t namesize = read_number (hd.size, sizeof (hd.size)); +- *name = grub_malloc (namesize + 1); ++ ++ if (grub_add (namesize, 1, &sz)) ++ return grub_error (GRUB_ERR_BAD_FS, N_("name size overflow")); ++ ++ *name = grub_malloc (sz); + if (*name == NULL) + return grub_errno; + err = grub_disk_read (data->disk, 0, +@@ -117,15 +123,19 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, + { + grub_err_t err; + grub_size_t linksize = read_number (hd.size, sizeof (hd.size)); +- if (data->linkname_alloc < linksize + 1) ++ ++ if (grub_add (linksize, 1, &sz)) ++ return grub_error (GRUB_ERR_BAD_FS, N_("link size overflow")); ++ ++ if (data->linkname_alloc < sz) + { + char *n; +- n = grub_calloc (2, linksize + 1); ++ n = grub_calloc (2, sz); + if (!n) + return grub_errno; + grub_free (data->linkname); + data->linkname = n; +- data->linkname_alloc = 2 * (linksize + 1); ++ data->linkname_alloc = 2 * (sz); + } + + err = grub_disk_read (data->disk, 0, +@@ -148,7 +158,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name, + while (extra_size < sizeof (hd.prefix) + && hd.prefix[extra_size]) + extra_size++; +- *name = grub_malloc (sizeof (hd.name) + extra_size + 2); ++ ++ if (grub_add (sizeof (hd.name) + 2, extra_size, &sz)) ++ return grub_error (GRUB_ERR_BAD_FS, N_("long name size overflow")); ++ *name = grub_malloc (sz); + if (*name == NULL) + return grub_errno; + if (hd.prefix[0]) +-- +2.48.1 + diff --git a/0005-fs-hfsplus-Set-a-grub_errno-if-mount-fails.patch b/0005-fs-hfsplus-Set-a-grub_errno-if-mount-fails.patch new file mode 100644 index 0000000..54e0cf9 --- /dev/null +++ b/0005-fs-hfsplus-Set-a-grub_errno-if-mount-fails.patch @@ -0,0 +1,38 @@ +From 3f1980191c693670380aa9aa5a949c5574a3bd04 Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Sun, 12 May 2024 06:22:51 +0100 +Subject: [PATCH 05/20] fs/hfsplus: Set a grub_errno if mount fails + +It was possible for mount to fail but not set grub_errno. This led to +a possible double decrement of the module reference count if the NULL +page was mapped. + +Fixing in general as a similar bug was fixed in commit 61b13c187 +(fs/hfsplus: Set grub_errno to prevent NULL pointer access) and there +are likely more variants around. + +Fixes: CVE-2024-45783 + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/fs/hfsplus.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c +index 295822f694..de71fd486b 100644 +--- a/grub-core/fs/hfsplus.c ++++ b/grub-core/fs/hfsplus.c +@@ -405,7 +405,7 @@ grub_hfsplus_mount (grub_disk_t disk) + + fail: + +- if (grub_errno == GRUB_ERR_OUT_OF_RANGE) ++ if (grub_errno == GRUB_ERR_OUT_OF_RANGE || grub_errno == GRUB_ERR_NONE) + grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem"); + + grub_free (data); +-- +2.48.1 + diff --git a/0006-kern-file-Ensure-file-data-is-set.patch b/0006-kern-file-Ensure-file-data-is-set.patch new file mode 100644 index 0000000..4a50013 --- /dev/null +++ b/0006-kern-file-Ensure-file-data-is-set.patch @@ -0,0 +1,35 @@ +From 07482c2ab034df5069761319e4969551c3dcc6e1 Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Sun, 12 May 2024 03:01:40 +0100 +Subject: [PATCH 06/20] kern/file: Ensure file->data is set + +This is to avoid a generic issue were some filesystems would not set +data and also not set a grub_errno. This meant it was possible for many +filesystems to grub_dl_unref() themselves multiple times resulting in +it being possible to unload the filesystems while there were still +references to them, e.g., via a loopback. + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/kern/file.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c +index 750177248f..e990507fca 100644 +--- a/grub-core/kern/file.c ++++ b/grub-core/kern/file.c +@@ -114,6 +114,9 @@ grub_file_open (const char *name, enum grub_file_type type) + if ((file->fs->fs_open) (file, file_name) != GRUB_ERR_NONE) + goto fail; + ++ if (file->data == NULL) ++ goto fail; ++ + file->name = grub_strdup (name); + grub_errno = GRUB_ERR_NONE; + +-- +2.48.1 + diff --git a/0007-kern-file-Implement-filesystem-reference-counting.patch b/0007-kern-file-Implement-filesystem-reference-counting.patch new file mode 100644 index 0000000..48ca2a8 --- /dev/null +++ b/0007-kern-file-Implement-filesystem-reference-counting.patch @@ -0,0 +1,443 @@ +From 8e9240826c7d230cab6d52724d2cf3759e6f0d3f Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Sun, 12 May 2024 10:15:03 +0100 +Subject: [PATCH 07/20] kern/file: Implement filesystem reference counting + +The grub_file_open() and grub_file_close() should be the only places +that allow a reference to a filesystem to stay open. So, add grub_dl_t +to grub_fs_t and set this in the GRUB_MOD_INIT() for each filesystem to +avoid issues when filesystems forget to do it themselves or do not track +their own references, e.g. squash4. + +The fs_label(), fs_uuid(), fs_mtime() and fs_read() should all ref and +unref in the same function but it is essentially redundant in GRUB +single threaded model. + +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/fs/affs.c | 1 + + grub-core/fs/bfs.c | 1 + + grub-core/fs/btrfs.c | 1 + + grub-core/fs/cbfs.c | 1 + + grub-core/fs/cpio.c | 1 + + grub-core/fs/cpio_be.c | 1 + + grub-core/fs/ext2.c | 1 + + grub-core/fs/f2fs.c | 1 + + grub-core/fs/fat.c | 1 + + grub-core/fs/hfs.c | 1 + + grub-core/fs/hfsplus.c | 1 + + grub-core/fs/iso9660.c | 1 + + grub-core/fs/jfs.c | 1 + + grub-core/fs/minix.c | 1 + + grub-core/fs/newc.c | 1 + + grub-core/fs/nilfs2.c | 1 + + grub-core/fs/ntfs.c | 1 + + grub-core/fs/odc.c | 1 + + grub-core/fs/proc.c | 1 + + grub-core/fs/reiserfs.c | 1 + + grub-core/fs/romfs.c | 1 + + grub-core/fs/sfs.c | 1 + + grub-core/fs/squash4.c | 1 + + grub-core/fs/tar.c | 1 + + grub-core/fs/udf.c | 1 + + grub-core/fs/ufs.c | 1 + + grub-core/fs/xfs.c | 1 + + grub-core/fs/zfs/zfs.c | 1 + + grub-core/kern/file.c | 7 +++++++ + include/grub/fs.h | 4 ++++ + 30 files changed, 39 insertions(+) + +diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c +index ed606b3f15..9b0afb9541 100644 +--- a/grub-core/fs/affs.c ++++ b/grub-core/fs/affs.c +@@ -703,6 +703,7 @@ static struct grub_fs grub_affs_fs = + + GRUB_MOD_INIT(affs) + { ++ grub_affs_fs.mod = mod; + grub_fs_register (&grub_affs_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c +index 07cb3e3acf..f37b168958 100644 +--- a/grub-core/fs/bfs.c ++++ b/grub-core/fs/bfs.c +@@ -1106,6 +1106,7 @@ GRUB_MOD_INIT (bfs) + { + COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE == + sizeof (struct grub_bfs_extent)); ++ grub_bfs_fs.mod = mod; + grub_fs_register (&grub_bfs_fs); + } + +diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c +index 7e12dce9c2..0dd9a817ee 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -3565,6 +3565,7 @@ relpath_set_env (struct grub_env_var *var, + + GRUB_MOD_INIT (btrfs) + { ++ grub_btrfs_fs.mod = mod; + grub_fs_register (&grub_btrfs_fs); + cmd_info = grub_register_command("btrfs-info", grub_cmd_btrfs_info, + "DEVICE", +diff --git a/grub-core/fs/cbfs.c b/grub-core/fs/cbfs.c +index 8ab7106afb..2332745fe8 100644 +--- a/grub-core/fs/cbfs.c ++++ b/grub-core/fs/cbfs.c +@@ -390,6 +390,7 @@ GRUB_MOD_INIT (cbfs) + #if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN) + init_cbfsdisk (); + #endif ++ grub_cbfs_fs.mod = mod; + grub_fs_register (&grub_cbfs_fs); + } + +diff --git a/grub-core/fs/cpio.c b/grub-core/fs/cpio.c +index dab5f98988..1799f7ff5a 100644 +--- a/grub-core/fs/cpio.c ++++ b/grub-core/fs/cpio.c +@@ -52,6 +52,7 @@ read_number (const grub_uint16_t *arr, grub_size_t size) + + GRUB_MOD_INIT (cpio) + { ++ grub_cpio_fs.mod = mod; + grub_fs_register (&grub_cpio_fs); + } + +diff --git a/grub-core/fs/cpio_be.c b/grub-core/fs/cpio_be.c +index 8465488921..7bed1b848c 100644 +--- a/grub-core/fs/cpio_be.c ++++ b/grub-core/fs/cpio_be.c +@@ -52,6 +52,7 @@ read_number (const grub_uint16_t *arr, grub_size_t size) + + GRUB_MOD_INIT (cpio_be) + { ++ grub_cpio_fs.mod = mod; + grub_fs_register (&grub_cpio_fs); + } + +diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c +index e1cc5e62aa..04f5d04e14 100644 +--- a/grub-core/fs/ext2.c ++++ b/grub-core/fs/ext2.c +@@ -1123,6 +1123,7 @@ static struct grub_fs grub_ext2_fs = + + GRUB_MOD_INIT(ext2) + { ++ grub_ext2_fs.mod = mod; + grub_fs_register (&grub_ext2_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c +index 855e24618c..7e48796036 100644 +--- a/grub-core/fs/f2fs.c ++++ b/grub-core/fs/f2fs.c +@@ -1350,6 +1350,7 @@ static struct grub_fs grub_f2fs_fs = { + + GRUB_MOD_INIT (f2fs) + { ++ grub_f2fs_fs.mod = mod; + grub_fs_register (&grub_f2fs_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c +index c5efed7241..6e62b915dd 100644 +--- a/grub-core/fs/fat.c ++++ b/grub-core/fs/fat.c +@@ -1312,6 +1312,7 @@ GRUB_MOD_INIT(fat) + #endif + { + COMPILE_TIME_ASSERT (sizeof (struct grub_fat_dir_entry) == 32); ++ grub_fat_fs.mod = mod; + grub_fs_register (&grub_fat_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c +index 920112b03e..ce7581dd5f 100644 +--- a/grub-core/fs/hfs.c ++++ b/grub-core/fs/hfs.c +@@ -1434,6 +1434,7 @@ static struct grub_fs grub_hfs_fs = + + GRUB_MOD_INIT(hfs) + { ++ grub_hfs_fs.mod = mod; + if (!grub_is_lockdown ()) + grub_fs_register (&grub_hfs_fs); + my_mod = mod; +diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c +index de71fd486b..3f203abccd 100644 +--- a/grub-core/fs/hfsplus.c ++++ b/grub-core/fs/hfsplus.c +@@ -1176,6 +1176,7 @@ static struct grub_fs grub_hfsplus_fs = + + GRUB_MOD_INIT(hfsplus) + { ++ grub_hfsplus_fs.mod = mod; + grub_fs_register (&grub_hfsplus_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/iso9660.c b/grub-core/fs/iso9660.c +index 8c348b59a5..5aabca284b 100644 +--- a/grub-core/fs/iso9660.c ++++ b/grub-core/fs/iso9660.c +@@ -1247,6 +1247,7 @@ static struct grub_fs grub_iso9660_fs = + + GRUB_MOD_INIT(iso9660) + { ++ grub_iso9660_fs.mod = mod; + grub_fs_register (&grub_iso9660_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c +index 6f7c439049..3139e53329 100644 +--- a/grub-core/fs/jfs.c ++++ b/grub-core/fs/jfs.c +@@ -963,6 +963,7 @@ static struct grub_fs grub_jfs_fs = + + GRUB_MOD_INIT(jfs) + { ++ grub_jfs_fs.mod = mod; + grub_fs_register (&grub_jfs_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c +index 5354951d10..b7679c3e25 100644 +--- a/grub-core/fs/minix.c ++++ b/grub-core/fs/minix.c +@@ -734,6 +734,7 @@ GRUB_MOD_INIT(minix) + #endif + #endif + { ++ grub_minix_fs.mod = mod; + grub_fs_register (&grub_minix_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/newc.c b/grub-core/fs/newc.c +index 4fb8b2e3d2..43b7f8b642 100644 +--- a/grub-core/fs/newc.c ++++ b/grub-core/fs/newc.c +@@ -64,6 +64,7 @@ read_number (const char *str, grub_size_t size) + + GRUB_MOD_INIT (newc) + { ++ grub_cpio_fs.mod = mod; + grub_fs_register (&grub_cpio_fs); + } + +diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c +index fc7374ead4..4e1e717386 100644 +--- a/grub-core/fs/nilfs2.c ++++ b/grub-core/fs/nilfs2.c +@@ -1231,6 +1231,7 @@ GRUB_MOD_INIT (nilfs2) + grub_nilfs2_dat_entry)); + COMPILE_TIME_ASSERT (1 << LOG_INODE_SIZE + == sizeof (struct grub_nilfs2_inode)); ++ grub_nilfs2_fs.mod = mod; + grub_fs_register (&grub_nilfs2_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c +index de435aa14d..560917dc2c 100644 +--- a/grub-core/fs/ntfs.c ++++ b/grub-core/fs/ntfs.c +@@ -1320,6 +1320,7 @@ static struct grub_fs grub_ntfs_fs = + + GRUB_MOD_INIT (ntfs) + { ++ grub_ntfs_fs.mod = mod; + grub_fs_register (&grub_ntfs_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/odc.c b/grub-core/fs/odc.c +index 790000622d..8e4e8aeac8 100644 +--- a/grub-core/fs/odc.c ++++ b/grub-core/fs/odc.c +@@ -52,6 +52,7 @@ read_number (const char *str, grub_size_t size) + + GRUB_MOD_INIT (odc) + { ++ grub_cpio_fs.mod = mod; + grub_fs_register (&grub_cpio_fs); + } + +diff --git a/grub-core/fs/proc.c b/grub-core/fs/proc.c +index 5f516502d4..bcde433495 100644 +--- a/grub-core/fs/proc.c ++++ b/grub-core/fs/proc.c +@@ -192,6 +192,7 @@ static struct grub_fs grub_procfs_fs = + + GRUB_MOD_INIT (procfs) + { ++ grub_procfs_fs.mod = mod; + grub_disk_dev_register (&grub_procfs_dev); + grub_fs_register (&grub_procfs_fs); + } +diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c +index 36b26ac98a..c3850e0138 100644 +--- a/grub-core/fs/reiserfs.c ++++ b/grub-core/fs/reiserfs.c +@@ -1417,6 +1417,7 @@ static struct grub_fs grub_reiserfs_fs = + + GRUB_MOD_INIT(reiserfs) + { ++ grub_reiserfs_fs.mod = mod; + grub_fs_register (&grub_reiserfs_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c +index 1f7dcfca1d..56b0b2b2f3 100644 +--- a/grub-core/fs/romfs.c ++++ b/grub-core/fs/romfs.c +@@ -475,6 +475,7 @@ static struct grub_fs grub_romfs_fs = + + GRUB_MOD_INIT(romfs) + { ++ grub_romfs_fs.mod = mod; + grub_fs_register (&grub_romfs_fs); + } + +diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c +index 983e880088..f0d7cac435 100644 +--- a/grub-core/fs/sfs.c ++++ b/grub-core/fs/sfs.c +@@ -779,6 +779,7 @@ static struct grub_fs grub_sfs_fs = + + GRUB_MOD_INIT(sfs) + { ++ grub_sfs_fs.mod = mod; + grub_fs_register (&grub_sfs_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c +index a30e6ebe14..6e9d63874c 100644 +--- a/grub-core/fs/squash4.c ++++ b/grub-core/fs/squash4.c +@@ -1044,6 +1044,7 @@ static struct grub_fs grub_squash_fs = + + GRUB_MOD_INIT(squash4) + { ++ grub_squash_fs.mod = mod; + grub_fs_register (&grub_squash_fs); + } + +diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c +index a9e39b0eb6..a608ac9c9f 100644 +--- a/grub-core/fs/tar.c ++++ b/grub-core/fs/tar.c +@@ -349,6 +349,7 @@ static struct grub_fs grub_cpio_fs = { + + GRUB_MOD_INIT (tar) + { ++ grub_cpio_fs.mod = mod; + grub_fs_register (&grub_cpio_fs); + } + +diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c +index b836e61075..8765c633c6 100644 +--- a/grub-core/fs/udf.c ++++ b/grub-core/fs/udf.c +@@ -1455,6 +1455,7 @@ static struct grub_fs grub_udf_fs = { + + GRUB_MOD_INIT (udf) + { ++ grub_udf_fs.mod = mod; + grub_fs_register (&grub_udf_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c +index 01235101b4..e82d9356d7 100644 +--- a/grub-core/fs/ufs.c ++++ b/grub-core/fs/ufs.c +@@ -899,6 +899,7 @@ GRUB_MOD_INIT(ufs1) + #endif + #endif + { ++ grub_ufs_fs.mod = mod; + grub_fs_register (&grub_ufs_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index 1ce5fa4fc4..c17e54e447 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -1281,6 +1281,7 @@ static struct grub_fs grub_xfs_fs = + + GRUB_MOD_INIT(xfs) + { ++ grub_xfs_fs.mod = mod; + grub_fs_register (&grub_xfs_fs); + my_mod = mod; + } +diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c +index b5453e0062..a497b18695 100644 +--- a/grub-core/fs/zfs/zfs.c ++++ b/grub-core/fs/zfs/zfs.c +@@ -4424,6 +4424,7 @@ static struct grub_fs grub_zfs_fs = { + GRUB_MOD_INIT (zfs) + { + COMPILE_TIME_ASSERT (sizeof (zap_leaf_chunk_t) == ZAP_LEAF_CHUNKSIZE); ++ grub_zfs_fs.mod = mod; + grub_fs_register (&grub_zfs_fs); + #ifndef GRUB_UTIL + my_mod = mod; +diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c +index e990507fca..6e7efe89ab 100644 +--- a/grub-core/kern/file.c ++++ b/grub-core/kern/file.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + void (*EXPORT_VAR (grub_grubnet_fini)) (void); + +@@ -117,6 +118,9 @@ grub_file_open (const char *name, enum grub_file_type type) + if (file->data == NULL) + goto fail; + ++ if (file->fs->mod) ++ grub_dl_ref (file->fs->mod); ++ + file->name = grub_strdup (name); + grub_errno = GRUB_ERR_NONE; + +@@ -197,6 +201,9 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len) + grub_err_t + grub_file_close (grub_file_t file) + { ++ if (file->fs->mod) ++ grub_dl_unref (file->fs->mod); ++ + if (file->fs->fs_close) + (file->fs->fs_close) (file); + +diff --git a/include/grub/fs.h b/include/grub/fs.h +index 4c380e3341..9c8206133d 100644 +--- a/include/grub/fs.h ++++ b/include/grub/fs.h +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + #include + /* For embedding types. */ +@@ -57,6 +58,9 @@ struct grub_fs + /* My name. */ + const char *name; + ++ /* My module */ ++ grub_dl_t mod; ++ + /* Call HOOK with each file under DIR. */ + grub_err_t (*fs_dir) (grub_device_t device, const char *path, + grub_fs_dir_hook_t hook, void *hook_data); +-- +2.48.1 + diff --git a/0008-net-Fix-OOB-write-in-grub_net_search_config_file.patch b/0008-net-Fix-OOB-write-in-grub_net_search_config_file.patch new file mode 100644 index 0000000..88a923e --- /dev/null +++ b/0008-net-Fix-OOB-write-in-grub_net_search_config_file.patch @@ -0,0 +1,83 @@ +From de9400db3f181e059f9ab1bb6a667ae2c29baf03 Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Fri, 15 Nov 2024 13:12:09 +0000 +Subject: [PATCH 08/20] net: Fix OOB write in grub_net_search_config_file() + +The function included a call to grub_strcpy() which copied data from an +environment variable to a buffer allocated in grub_cmd_normal(). The +grub_cmd_normal() didn't consider the length of the environment variable. +So, the copy operation could exceed the allocation and lead to an OOB +write. Fix the issue by replacing grub_strcpy() with grub_strlcpy() and +pass the underlying buffers size to the grub_net_search_config_file(). + +Fixes: CVE-2025-0624 + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/net/net.c | 7 ++++--- + grub-core/normal/main.c | 2 +- + include/grub/net.h | 2 +- + 3 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/grub-core/net/net.c b/grub-core/net/net.c +index 22221dc6a0..df13c3aaaa 100644 +--- a/grub-core/net/net.c ++++ b/grub-core/net/net.c +@@ -1912,14 +1912,15 @@ grub_config_search_through (char *config, char *suffix, + } + + grub_err_t +-grub_net_search_config_file (char *config) ++grub_net_search_config_file (char *config, grub_size_t config_buf_len) + { +- grub_size_t config_len; ++ grub_size_t config_len, suffix_len; + char *suffix; + + config_len = grub_strlen (config); + config[config_len] = '-'; + suffix = config + config_len + 1; ++ suffix_len = config_buf_len - (config_len + 1); + + struct grub_net_network_level_interface *inf; + FOR_NET_NETWORK_LEVEL_INTERFACES (inf) +@@ -1945,7 +1946,7 @@ grub_net_search_config_file (char *config) + + if (client_uuid) + { +- grub_strcpy (suffix, client_uuid); ++ grub_strlcpy (suffix, client_uuid, suffix_len); + if (grub_config_search_through (config, suffix, 1, 0) == 0) + return GRUB_ERR_NONE; + } +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index b08fd6977d..f2679c4378 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -451,7 +451,7 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), + + if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && + !disable_net_search) +- grub_net_search_config_file (config); ++ grub_net_search_config_file (config, config_len); + + grub_enter_normal_mode (config); + grub_free (config); +diff --git a/include/grub/net.h b/include/grub/net.h +index dfb089a35c..abb637eaa2 100644 +--- a/include/grub/net.h ++++ b/include/grub/net.h +@@ -652,7 +652,7 @@ void + grub_net_remove_dns_server (const struct grub_net_network_level_address *s); + + grub_err_t +-grub_net_search_config_file (char *config); ++grub_net_search_config_file (char *config, grub_size_t config_buf_len); + + extern char *grub_net_default_server; + +-- +2.48.1 + diff --git a/0009-video-readers-jpeg-Do-not-permit-duplicate-SOF0-mark.patch b/0009-video-readers-jpeg-Do-not-permit-duplicate-SOF0-mark.patch new file mode 100644 index 0000000..e6a7ce7 --- /dev/null +++ b/0009-video-readers-jpeg-Do-not-permit-duplicate-SOF0-mark.patch @@ -0,0 +1,36 @@ +From c3093b6240302e52438469857fec616aa4b294a3 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Fri, 8 Mar 2024 22:47:20 +1100 +Subject: [PATCH 09/20] video/readers/jpeg: Do not permit duplicate SOF0 + markers in JPEG + +Otherwise a subsequent header could change the height and width +allowing future OOB writes. + +Fixes: CVE-2024-45774 + +Reported-by: Nils Langius +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/video/readers/jpeg.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c +index ae634fd419..631a893564 100644 +--- a/grub-core/video/readers/jpeg.c ++++ b/grub-core/video/readers/jpeg.c +@@ -339,6 +339,10 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + ++ if (data->image_height != 0 || data->image_width != 0) ++ return grub_error (GRUB_ERR_BAD_FILE_TYPE, ++ "jpeg: cannot have duplicate SOF0 markers"); ++ + if (grub_jpeg_get_byte (data) != 8) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: only 8-bit precision is supported"); +-- +2.48.1 + diff --git a/0010-commands-extcmd-Missing-check-for-failed-allocation.patch b/0010-commands-extcmd-Missing-check-for-failed-allocation.patch new file mode 100644 index 0000000..111f663 --- /dev/null +++ b/0010-commands-extcmd-Missing-check-for-failed-allocation.patch @@ -0,0 +1,37 @@ +From 5d6f17ba4e94fe00b80498e9ce1aac57e22adba7 Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Fri, 22 Nov 2024 06:27:55 +0000 +Subject: [PATCH 10/20] commands/extcmd: Missing check for failed allocation + +The grub_extcmd_dispatcher() calls grub_arg_list_alloc() to allocate +a grub_arg_list struct but it does not verify the allocation was successful. +In case of failed allocation the NULL state pointer can be accessed in +parse_option() through grub_arg_parse() which may lead to a security issue. + +Fixes: CVE-2024-45775 + +Reported-by: Nils Langius +Signed-off-by: Lidong Chen +Reviewed-by: Daniel Kiper +Reviewed-by: Alec Brown +--- + grub-core/commands/extcmd.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/grub-core/commands/extcmd.c b/grub-core/commands/extcmd.c +index 4ac111a991..95bd71235a 100644 +--- a/grub-core/commands/extcmd.c ++++ b/grub-core/commands/extcmd.c +@@ -49,6 +49,9 @@ grub_extcmd_dispatcher (struct grub_command *cmd, int argc, char **args, + } + + state = grub_arg_list_alloc (ext, argc, args); ++ if (state == NULL) ++ return grub_errno; ++ + if (grub_arg_parse (ext, argc, args, state, &new_args, &new_argc)) + { + context.state = state; +-- +2.48.1 + diff --git a/0011-commands-pgp-Unregister-the-check_signatures-hooks-o.patch b/0011-commands-pgp-Unregister-the-check_signatures-hooks-o.patch new file mode 100644 index 0000000..56a2a1f --- /dev/null +++ b/0011-commands-pgp-Unregister-the-check_signatures-hooks-o.patch @@ -0,0 +1,34 @@ +From a496d7fbb80826b341ec1a578704dd574b716d68 Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Fri, 1 Nov 2024 19:24:29 +0000 +Subject: [PATCH 11/20] commands/pgp: Unregister the "check_signatures" hooks + on module unload + +If the hooks are not removed they can be called after the module has +been unloaded leading to an use-after-free. + +Fixes: CVE-2025-0622 + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/commands/pgp.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c +index 847a5046a5..fa3ef5c754 100644 +--- a/grub-core/commands/pgp.c ++++ b/grub-core/commands/pgp.c +@@ -982,6 +982,8 @@ GRUB_MOD_INIT(pgp) + + GRUB_MOD_FINI(pgp) + { ++ grub_register_variable_hook ("check_signatures", NULL, NULL); ++ grub_env_unset ("check_signatures"); + grub_verifier_unregister (&grub_pubkey_verifier); + grub_unregister_extcmd (cmd); + grub_unregister_extcmd (cmd_trust); +-- +2.48.1 + diff --git a/0012-normal-Remove-variables-hooks-on-module-unload.patch b/0012-normal-Remove-variables-hooks-on-module-unload.patch new file mode 100644 index 0000000..4c34484 --- /dev/null +++ b/0012-normal-Remove-variables-hooks-on-module-unload.patch @@ -0,0 +1,40 @@ +From cf9108c54b25bd485832bf8930c18abf2935b35e Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Fri, 1 Nov 2024 23:46:55 +0000 +Subject: [PATCH 12/20] normal: Remove variables hooks on module unload + +The normal module does not entirely cleanup after itself in +its GRUB_MOD_FINI() leaving a few variables hooks in place. +It is not possible to unload normal module now but fix the +issues for completeness. + +On the occasion replace 0s with NULLs for "pager" variable +hooks unregister. + +Fixes: CVE-2025-0622 + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/normal/main.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index f2679c4378..c9eda889ca 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -694,7 +694,9 @@ GRUB_MOD_FINI(normal) + grub_xputs = grub_xputs_saved; + + grub_set_history (0); +- grub_register_variable_hook ("pager", 0, 0); ++ grub_register_variable_hook ("pager", NULL, NULL); ++ grub_register_variable_hook ("color_normal", NULL, NULL); ++ grub_register_variable_hook ("color_highlight", NULL, NULL); + grub_fs_autoload_hook = 0; + grub_unregister_command (cmd_clear); + } +-- +2.48.1 + diff --git a/0013-gettext-Remove-variables-hooks-on-module-unload.patch b/0013-gettext-Remove-variables-hooks-on-module-unload.patch new file mode 100644 index 0000000..459917a --- /dev/null +++ b/0013-gettext-Remove-variables-hooks-on-module-unload.patch @@ -0,0 +1,37 @@ +From dff23721425f363f2d1b6ee41be44af69cdd4aab Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Fri, 1 Nov 2024 23:52:06 +0000 +Subject: [PATCH 13/20] gettext: Remove variables hooks on module unload + +The gettext module does not entirely cleanup after itself in +its GRUB_MOD_FINI() leaving a few variables hooks in place. +It is not possible to unload gettext module because normal +module depends on it. Though fix the issues for completeness. + +Fixes: CVE-2025-0622 + +Reported-by: B Horn +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/gettext/gettext.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c +index 7a1c14e4f3..e4f4f8ee66 100644 +--- a/grub-core/gettext/gettext.c ++++ b/grub-core/gettext/gettext.c +@@ -535,6 +535,10 @@ GRUB_MOD_INIT (gettext) + + GRUB_MOD_FINI (gettext) + { ++ grub_register_variable_hook ("locale_dir", NULL, NULL); ++ grub_register_variable_hook ("secondary_locale_dir", NULL, NULL); ++ grub_register_variable_hook ("lang", NULL, NULL); ++ + grub_gettext_delete_list (&main_context); + grub_gettext_delete_list (&secondary_context); + +-- +2.48.1 + diff --git a/0014-gettext-Integer-overflow-leads-to-heap-OOB-write-or-.patch b/0014-gettext-Integer-overflow-leads-to-heap-OOB-write-or-.patch new file mode 100644 index 0000000..b0ab301 --- /dev/null +++ b/0014-gettext-Integer-overflow-leads-to-heap-OOB-write-or-.patch @@ -0,0 +1,39 @@ +From 9126fb474968a1f4ea8e233c5746fa735a07b3d4 Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Fri, 22 Nov 2024 06:27:56 +0000 +Subject: [PATCH 14/20] gettext: Integer overflow leads to heap OOB write or + read + +Calculation of ctx->grub_gettext_msg_list size in grub_mofile_open() may +overflow leading to subsequent OOB write or read. This patch fixes the +issue by replacing grub_zalloc() and explicit multiplication with +grub_calloc() which does the same thing in safe manner. + +Fixes: CVE-2024-45776 + +Reported-by: Nils Langius +Signed-off-by: Lidong Chen +Reviewed-by: Daniel Kiper +Reviewed-by: Alec Brown +--- + grub-core/gettext/gettext.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c +index e4f4f8ee66..63bb1ab73f 100644 +--- a/grub-core/gettext/gettext.c ++++ b/grub-core/gettext/gettext.c +@@ -323,8 +323,8 @@ grub_mofile_open (struct grub_gettext_context *ctx, + for (ctx->grub_gettext_max_log = 0; ctx->grub_gettext_max >> ctx->grub_gettext_max_log; + ctx->grub_gettext_max_log++); + +- ctx->grub_gettext_msg_list = grub_zalloc (ctx->grub_gettext_max +- * sizeof (ctx->grub_gettext_msg_list[0])); ++ ctx->grub_gettext_msg_list = grub_calloc (ctx->grub_gettext_max, ++ sizeof (ctx->grub_gettext_msg_list[0])); + if (!ctx->grub_gettext_msg_list) + { + grub_file_close (fd); +-- +2.48.1 + diff --git a/0015-gettext-Integer-overflow-leads-to-heap-OOB-write.patch b/0015-gettext-Integer-overflow-leads-to-heap-OOB-write.patch new file mode 100644 index 0000000..506afee --- /dev/null +++ b/0015-gettext-Integer-overflow-leads-to-heap-OOB-write.patch @@ -0,0 +1,56 @@ +From 1f8d74717d2bebd1206143c1acbf720be9097011 Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Fri, 22 Nov 2024 06:27:57 +0000 +Subject: [PATCH 15/20] gettext: Integer overflow leads to heap OOB write + +The size calculation of the translation buffer in +grub_gettext_getstr_from_position() may overflow +to 0 leading to heap OOB write. This patch fixes +the issue by using grub_add() and checking for +an overflow. + +Fixes: CVE-2024-45777 + +Reported-by: Nils Langius +Signed-off-by: Lidong Chen +Reviewed-by: Daniel Kiper +Reviewed-by: Alec Brown +--- + grub-core/gettext/gettext.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c +index 63bb1ab73f..9ffc734284 100644 +--- a/grub-core/gettext/gettext.c ++++ b/grub-core/gettext/gettext.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -99,6 +100,7 @@ grub_gettext_getstr_from_position (struct grub_gettext_context *ctx, + char *translation; + struct string_descriptor desc; + grub_err_t err; ++ grub_size_t alloc_sz; + + internal_position = (off + position * sizeof (desc)); + +@@ -109,7 +111,10 @@ grub_gettext_getstr_from_position (struct grub_gettext_context *ctx, + length = grub_cpu_to_le32 (desc.length); + offset = grub_cpu_to_le32 (desc.offset); + +- translation = grub_malloc (length + 1); ++ if (grub_add (length, 1, &alloc_sz)) ++ return NULL; ++ ++ translation = grub_malloc (alloc_sz); + if (!translation) + return NULL; + +-- +2.48.1 + diff --git a/0016-commands-read-Fix-an-integer-overflow-when-supplying.patch b/0016-commands-read-Fix-an-integer-overflow-when-supplying.patch new file mode 100644 index 0000000..12b0d50 --- /dev/null +++ b/0016-commands-read-Fix-an-integer-overflow-when-supplying.patch @@ -0,0 +1,72 @@ +From fd945966dc04c01765dcf129d8884f0b22991e74 Mon Sep 17 00:00:00 2001 +From: Jonathan Bar Or +Date: Thu, 23 Jan 2025 19:17:05 +0100 +Subject: [PATCH 16/20] commands/read: Fix an integer overflow when supplying + more than 2^31 characters + +The grub_getline() function currently has a signed integer variable "i" +that can be overflown when user supplies more than 2^31 characters. +It results in a memory corruption of the allocated line buffer as well +as supplying large negative values to grub_realloc(). + +Fixes: CVE-2025-0690 + +Reported-by: Jonathan Bar Or +Signed-off-by: Jonathan Bar Or +Reviewed-by: Daniel Kiper +--- + grub-core/commands/read.c | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +diff --git a/grub-core/commands/read.c b/grub-core/commands/read.c +index 9bbc523f6b..b8597692e2 100644 +--- a/grub-core/commands/read.c ++++ b/grub-core/commands/read.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -38,13 +39,14 @@ static const struct grub_arg_option options[] = + static char * + grub_getline (int silent) + { +- int i; ++ grub_size_t i; + char *line; + char *tmp; + int c; ++ grub_size_t alloc_size; + + i = 0; +- line = grub_malloc (1 + i + sizeof('\0')); ++ line = grub_malloc (1 + sizeof('\0')); + if (! line) + return NULL; + +@@ -60,8 +62,17 @@ grub_getline (int silent) + line[i] = (char) c; + if (!silent) + grub_printf ("%c", c); +- i++; +- tmp = grub_realloc (line, 1 + i + sizeof('\0')); ++ if (grub_add (i, 1, &i)) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ return NULL; ++ } ++ if (grub_add (i, 1 + sizeof('\0'), &alloc_size)) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ return NULL; ++ } ++ tmp = grub_realloc (line, alloc_size); + if (! tmp) + { + grub_free (line); +-- +2.48.1 + diff --git a/0017-commands-minicmd-Block-the-dump-command-in-lockdown-.patch b/0017-commands-minicmd-Block-the-dump-command-in-lockdown-.patch new file mode 100644 index 0000000..b24a349 --- /dev/null +++ b/0017-commands-minicmd-Block-the-dump-command-in-lockdown-.patch @@ -0,0 +1,37 @@ +From 0f62a673fe00e83984810b7ec61b2d9a0bb8b9d4 Mon Sep 17 00:00:00 2001 +From: B Horn +Date: Thu, 18 Apr 2024 20:29:39 +0100 +Subject: [PATCH 17/20] commands/minicmd: Block the dump command in lockdown + mode + +The dump enables a user to read memory which should not be possible +in lockdown mode. + +Fixes: CVE-2025-1118 + +Reported-by: B Horn +Reported-by: Jonathan Bar Or +Signed-off-by: B Horn +Reviewed-by: Daniel Kiper +--- + grub-core/commands/minicmd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c +index fa498931ed..903af33131 100644 +--- a/grub-core/commands/minicmd.c ++++ b/grub-core/commands/minicmd.c +@@ -203,8 +203,8 @@ GRUB_MOD_INIT(minicmd) + grub_register_command ("help", grub_mini_cmd_help, + 0, N_("Show this message.")); + cmd_dump = +- grub_register_command ("dump", grub_mini_cmd_dump, +- N_("ADDR [SIZE]"), N_("Show memory contents.")); ++ grub_register_command_lockdown ("dump", grub_mini_cmd_dump, ++ N_("ADDR [SIZE]"), N_("Show memory contents.")); + cmd_rmmod = + grub_register_command ("rmmod", grub_mini_cmd_rmmod, + N_("MODULE"), N_("Remove a module.")); +-- +2.48.1 + diff --git a/0018-fs-bfs-Disable-under-lockdown.patch b/0018-fs-bfs-Disable-under-lockdown.patch new file mode 100644 index 0000000..8d6740d --- /dev/null +++ b/0018-fs-bfs-Disable-under-lockdown.patch @@ -0,0 +1,55 @@ +From 2cb6585529e7d1e522d71a13f382d8cc3d326555 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Sat, 23 Mar 2024 15:59:43 +1100 +Subject: [PATCH 18/20] fs/bfs: Disable under lockdown + +The BFS is not fuzz-clean. Don't allow it to be loaded under lockdown. +This will also disable the AFS. + +Fixes: CVE-2024-45778 +Fixes: CVE-2024-45779 + +Reported-by: Nils Langius +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/bfs.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/grub-core/fs/bfs.c b/grub-core/fs/bfs.c +index f37b168958..c92fd79168 100644 +--- a/grub-core/fs/bfs.c ++++ b/grub-core/fs/bfs.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -1106,8 +1107,11 @@ GRUB_MOD_INIT (bfs) + { + COMPILE_TIME_ASSERT (1 << LOG_EXTENT_SIZE == + sizeof (struct grub_bfs_extent)); +- grub_bfs_fs.mod = mod; +- grub_fs_register (&grub_bfs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_bfs_fs.mod = mod; ++ grub_fs_register (&grub_bfs_fs); ++ } + } + + #ifdef MODE_AFS +@@ -1116,5 +1120,6 @@ GRUB_MOD_FINI (afs) + GRUB_MOD_FINI (bfs) + #endif + { +- grub_fs_unregister (&grub_bfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_bfs_fs); + } +-- +2.48.1 + diff --git a/0019-fs-Disable-many-filesystems-under-lockdown.patch b/0019-fs-Disable-many-filesystems-under-lockdown.patch new file mode 100644 index 0000000..d076ad2 --- /dev/null +++ b/0019-fs-Disable-many-filesystems-under-lockdown.patch @@ -0,0 +1,394 @@ +From 8aba3dd18838329ae93c0ab43029d2236441b0ed Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Sat, 23 Mar 2024 16:20:45 +1100 +Subject: [PATCH 19/20] fs: Disable many filesystems under lockdown + +The idea is to permit the following: btrfs, cpio, exfat, ext, f2fs, fat, +hfsplus, iso9660, squash4, tar, xfs and zfs. + +The JFS, ReiserFS, romfs, UDF and UFS security vulnerabilities were +reported by Jonathan Bar Or . + +Fixes: CVE-2025-0677 +Fixes: CVE-2025-0684 +Fixes: CVE-2025-0685 +Fixes: CVE-2025-0686 +Fixes: CVE-2025-0689 + +Suggested-by: Daniel Axtens +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +--- + grub-core/fs/affs.c | 11 ++++++++--- + grub-core/fs/cbfs.c | 11 ++++++++--- + grub-core/fs/jfs.c | 11 ++++++++--- + grub-core/fs/minix.c | 11 ++++++++--- + grub-core/fs/nilfs2.c | 11 ++++++++--- + grub-core/fs/ntfs.c | 11 ++++++++--- + grub-core/fs/reiserfs.c | 11 ++++++++--- + grub-core/fs/romfs.c | 11 ++++++++--- + grub-core/fs/sfs.c | 11 ++++++++--- + grub-core/fs/udf.c | 11 ++++++++--- + grub-core/fs/ufs.c | 11 ++++++++--- + 11 files changed, 88 insertions(+), 33 deletions(-) + +diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c +index 9b0afb9541..520a001c75 100644 +--- a/grub-core/fs/affs.c ++++ b/grub-core/fs/affs.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -703,12 +704,16 @@ static struct grub_fs grub_affs_fs = + + GRUB_MOD_INIT(affs) + { +- grub_affs_fs.mod = mod; +- grub_fs_register (&grub_affs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_affs_fs.mod = mod; ++ grub_fs_register (&grub_affs_fs); ++ } + my_mod = mod; + } + + GRUB_MOD_FINI(affs) + { +- grub_fs_unregister (&grub_affs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_affs_fs); + } +diff --git a/grub-core/fs/cbfs.c b/grub-core/fs/cbfs.c +index 2332745fe8..b62c8777cf 100644 +--- a/grub-core/fs/cbfs.c ++++ b/grub-core/fs/cbfs.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -390,13 +391,17 @@ GRUB_MOD_INIT (cbfs) + #if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN) + init_cbfsdisk (); + #endif +- grub_cbfs_fs.mod = mod; +- grub_fs_register (&grub_cbfs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_cbfs_fs.mod = mod; ++ grub_fs_register (&grub_cbfs_fs); ++ } + } + + GRUB_MOD_FINI (cbfs) + { +- grub_fs_unregister (&grub_cbfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_cbfs_fs); + #if (defined (__i386__) || defined (__x86_64__)) && !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_MACHINE_XEN) + fini_cbfsdisk (); + #endif +diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c +index 3139e53329..d72e19088c 100644 +--- a/grub-core/fs/jfs.c ++++ b/grub-core/fs/jfs.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -963,12 +964,16 @@ static struct grub_fs grub_jfs_fs = + + GRUB_MOD_INIT(jfs) + { +- grub_jfs_fs.mod = mod; +- grub_fs_register (&grub_jfs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_jfs_fs.mod = mod; ++ grub_fs_register (&grub_jfs_fs); ++ } + my_mod = mod; + } + + GRUB_MOD_FINI(jfs) + { +- grub_fs_unregister (&grub_jfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_jfs_fs); + } +diff --git a/grub-core/fs/minix.c b/grub-core/fs/minix.c +index b7679c3e25..4440fcca83 100644 +--- a/grub-core/fs/minix.c ++++ b/grub-core/fs/minix.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -734,8 +735,11 @@ GRUB_MOD_INIT(minix) + #endif + #endif + { +- grub_minix_fs.mod = mod; +- grub_fs_register (&grub_minix_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_minix_fs.mod = mod; ++ grub_fs_register (&grub_minix_fs); ++ } + my_mod = mod; + } + +@@ -757,5 +761,6 @@ GRUB_MOD_FINI(minix) + #endif + #endif + { +- grub_fs_unregister (&grub_minix_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_minix_fs); + } +diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c +index 4e1e717386..26e6077ff2 100644 +--- a/grub-core/fs/nilfs2.c ++++ b/grub-core/fs/nilfs2.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -1231,12 +1232,16 @@ GRUB_MOD_INIT (nilfs2) + grub_nilfs2_dat_entry)); + COMPILE_TIME_ASSERT (1 << LOG_INODE_SIZE + == sizeof (struct grub_nilfs2_inode)); +- grub_nilfs2_fs.mod = mod; +- grub_fs_register (&grub_nilfs2_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_nilfs2_fs.mod = mod; ++ grub_fs_register (&grub_nilfs2_fs); ++ } + my_mod = mod; + } + + GRUB_MOD_FINI (nilfs2) + { +- grub_fs_unregister (&grub_nilfs2_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_nilfs2_fs); + } +diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c +index 560917dc2c..bce81947cf 100644 +--- a/grub-core/fs/ntfs.c ++++ b/grub-core/fs/ntfs.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -1320,12 +1321,16 @@ static struct grub_fs grub_ntfs_fs = + + GRUB_MOD_INIT (ntfs) + { +- grub_ntfs_fs.mod = mod; +- grub_fs_register (&grub_ntfs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_ntfs_fs.mod = mod; ++ grub_fs_register (&grub_ntfs_fs); ++ } + my_mod = mod; + } + + GRUB_MOD_FINI (ntfs) + { +- grub_fs_unregister (&grub_ntfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_ntfs_fs); + } +diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c +index c3850e0138..5d3c859502 100644 +--- a/grub-core/fs/reiserfs.c ++++ b/grub-core/fs/reiserfs.c +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -1417,12 +1418,16 @@ static struct grub_fs grub_reiserfs_fs = + + GRUB_MOD_INIT(reiserfs) + { +- grub_reiserfs_fs.mod = mod; +- grub_fs_register (&grub_reiserfs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_reiserfs_fs.mod = mod; ++ grub_fs_register (&grub_reiserfs_fs); ++ } + my_mod = mod; + } + + GRUB_MOD_FINI(reiserfs) + { +- grub_fs_unregister (&grub_reiserfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_reiserfs_fs); + } +diff --git a/grub-core/fs/romfs.c b/grub-core/fs/romfs.c +index 56b0b2b2f3..eafab03b25 100644 +--- a/grub-core/fs/romfs.c ++++ b/grub-core/fs/romfs.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -475,11 +476,15 @@ static struct grub_fs grub_romfs_fs = + + GRUB_MOD_INIT(romfs) + { +- grub_romfs_fs.mod = mod; +- grub_fs_register (&grub_romfs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_romfs_fs.mod = mod; ++ grub_fs_register (&grub_romfs_fs); ++ } + } + + GRUB_MOD_FINI(romfs) + { +- grub_fs_unregister (&grub_romfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_romfs_fs); + } +diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c +index f0d7cac435..88705b3a29 100644 +--- a/grub-core/fs/sfs.c ++++ b/grub-core/fs/sfs.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + + GRUB_MOD_LICENSE ("GPLv3+"); +@@ -779,12 +780,16 @@ static struct grub_fs grub_sfs_fs = + + GRUB_MOD_INIT(sfs) + { +- grub_sfs_fs.mod = mod; +- grub_fs_register (&grub_sfs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_sfs_fs.mod = mod; ++ grub_fs_register (&grub_sfs_fs); ++ } + my_mod = mod; + } + + GRUB_MOD_FINI(sfs) + { +- grub_fs_unregister (&grub_sfs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_sfs_fs); + } +diff --git a/grub-core/fs/udf.c b/grub-core/fs/udf.c +index 8765c633c6..3d5ee5af50 100644 +--- a/grub-core/fs/udf.c ++++ b/grub-core/fs/udf.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -1455,12 +1456,16 @@ static struct grub_fs grub_udf_fs = { + + GRUB_MOD_INIT (udf) + { +- grub_udf_fs.mod = mod; +- grub_fs_register (&grub_udf_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_udf_fs.mod = mod; ++ grub_fs_register (&grub_udf_fs); ++ } + my_mod = mod; + } + + GRUB_MOD_FINI (udf) + { +- grub_fs_unregister (&grub_udf_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_udf_fs); + } +diff --git a/grub-core/fs/ufs.c b/grub-core/fs/ufs.c +index e82d9356d7..8b5adbd48d 100644 +--- a/grub-core/fs/ufs.c ++++ b/grub-core/fs/ufs.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -899,8 +900,11 @@ GRUB_MOD_INIT(ufs1) + #endif + #endif + { +- grub_ufs_fs.mod = mod; +- grub_fs_register (&grub_ufs_fs); ++ if (!grub_is_lockdown ()) ++ { ++ grub_ufs_fs.mod = mod; ++ grub_fs_register (&grub_ufs_fs); ++ } + my_mod = mod; + } + +@@ -914,6 +918,7 @@ GRUB_MOD_FINI(ufs1) + #endif + #endif + { +- grub_fs_unregister (&grub_ufs_fs); ++ if (!grub_is_lockdown ()) ++ grub_fs_unregister (&grub_ufs_fs); + } + +-- +2.48.1 + diff --git a/0020-fs-Prevent-overflows-when-allocating-memory-for-arra.patch b/0020-fs-Prevent-overflows-when-allocating-memory-for-arra.patch new file mode 100644 index 0000000..518c5ae --- /dev/null +++ b/0020-fs-Prevent-overflows-when-allocating-memory-for-arra.patch @@ -0,0 +1,85 @@ +From 53a0f0ebe569a846de22085c654ea4fbdfb6a154 Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Tue, 21 Jan 2025 19:02:37 +0000 +Subject: [PATCH 20/20] fs: Prevent overflows when allocating memory for arrays + +Use grub_calloc() when allocating memory for arrays to ensure proper +overflow checks are in place. + +The HFS+ and squash4 security vulnerabilities were reported by +Jonathan Bar Or . + +Fixes: CVE-2025-0678 +Fixes: CVE-2025-1125 + +Signed-off-by: Lidong Chen +Reviewed-by: Daniel Kiper +--- + grub-core/fs/btrfs.c | 4 ++-- + grub-core/fs/hfspluscomp.c | 9 +++++++-- + grub-core/fs/squash4.c | 8 ++++---- + 3 files changed, 13 insertions(+), 8 deletions(-) + +diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c +index 0dd9a817ee..8d0147dac1 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -1409,8 +1409,8 @@ grub_btrfs_mount (grub_device_t dev) + } + + data->n_devices_allocated = 16; +- data->devices_attached = grub_malloc (sizeof (data->devices_attached[0]) +- * data->n_devices_allocated); ++ data->devices_attached = grub_calloc (data->n_devices_allocated, ++ sizeof (data->devices_attached[0])); + if (!data->devices_attached) + { + grub_free (data); +diff --git a/grub-core/fs/hfspluscomp.c b/grub-core/fs/hfspluscomp.c +index 48ae438d85..a80954ee61 100644 +--- a/grub-core/fs/hfspluscomp.c ++++ b/grub-core/fs/hfspluscomp.c +@@ -244,14 +244,19 @@ hfsplus_open_compressed_real (struct grub_hfsplus_file *node) + return 0; + } + node->compress_index_size = grub_le_to_cpu32 (index_size); +- node->compress_index = grub_malloc (node->compress_index_size +- * sizeof (node->compress_index[0])); ++ node->compress_index = grub_calloc (node->compress_index_size, ++ sizeof (node->compress_index[0])); + if (!node->compress_index) + { + node->compressed = 0; + grub_free (attr_node); + return grub_errno; + } ++ ++ /* ++ * The node->compress_index_size * sizeof (node->compress_index[0]) is safe here ++ * due to relevant checks done in grub_calloc() above. ++ */ + if (grub_hfsplus_read_file (node, 0, 0, + 0x104 + sizeof (index_size), + node->compress_index_size +diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c +index 6e9d63874c..77aa4fbf3a 100644 +--- a/grub-core/fs/squash4.c ++++ b/grub-core/fs/squash4.c +@@ -816,10 +816,10 @@ direct_read (struct grub_squash_data *data, + break; + } + total_blocks = ((total_size + data->blksz - 1) >> data->log2_blksz); +- ino->block_sizes = grub_malloc (total_blocks +- * sizeof (ino->block_sizes[0])); +- ino->cumulated_block_sizes = grub_malloc (total_blocks +- * sizeof (ino->cumulated_block_sizes[0])); ++ ino->block_sizes = grub_calloc (total_blocks, ++ sizeof (ino->block_sizes[0])); ++ ino->cumulated_block_sizes = grub_calloc (total_blocks, ++ sizeof (ino->cumulated_block_sizes[0])); + if (!ino->block_sizes || !ino->cumulated_block_sizes) + { + grub_free (ino->block_sizes); +-- +2.48.1 + diff --git a/grub2.changes b/grub2.changes index 6c8b000..1c7dc3a 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,61 @@ +------------------------------------------------------------------- +Fri Feb 14 03:49:09 UTC 2025 - Michael Chang + +- Security fixes for 2024 + * 0001-misc-Implement-grub_strlcpy.patch +- Fix CVE-2024-45781 (bsc#1233617) + * 0002-fs-ufs-Fix-a-heap-OOB-write.patch +- Fix CVE-2024-56737 (bsc#1234958) +- Fix CVE-2024-45782 (bsc#1233615) + * 0003-fs-hfs-Fix-stack-OOB-write-with-grub_strcpy.patch +- Fix CVE-2024-45780 (bsc#1233614) + * 0004-fs-tar-Integer-overflow-leads-to-heap-OOB-write.patch +- Fix CVE-2024-45783 (bsc#1233616) + * 0005-fs-hfsplus-Set-a-grub_errno-if-mount-fails.patch + * 0006-kern-file-Ensure-file-data-is-set.patch + * 0007-kern-file-Implement-filesystem-reference-counting.patch +- Fix CVE-2025-0624 (bsc#1236316) + * 0008-net-Fix-OOB-write-in-grub_net_search_config_file.patch +- Fix CVE-2024-45774 (bsc#1233609) + * 0009-video-readers-jpeg-Do-not-permit-duplicate-SOF0-mark.patch +- Fix CVE-2024-45775 (bsc#1233610) + * 0010-commands-extcmd-Missing-check-for-failed-allocation.patch +- Fix CVE-2025-0622 (bsc#1236317) + * 0011-commands-pgp-Unregister-the-check_signatures-hooks-o.patch +- Fix CVE-2025-0622 (bsc#1236317) + * 0012-normal-Remove-variables-hooks-on-module-unload.patch +- Fix CVE-2025-0622 (bsc#1236317) + * 0013-gettext-Remove-variables-hooks-on-module-unload.patch +- Fix CVE-2024-45776 (bsc#1233612) + * 0014-gettext-Integer-overflow-leads-to-heap-OOB-write-or-.patch +- Fix CVE-2024-45777 (bsc#1233613) + * 0015-gettext-Integer-overflow-leads-to-heap-OOB-write.patch +- Fix CVE-2025-0690 (bsc#1237012) + * 0016-commands-read-Fix-an-integer-overflow-when-supplying.patch +- Fix CVE-2025-1118 (bsc#1237013) + * 0017-commands-minicmd-Block-the-dump-command-in-lockdown-.patch +- Fix CVE-2024-45778 (bsc#1233606) +- Fix CVE-2024-45779 (bsc#1233608) + * 0018-fs-bfs-Disable-under-lockdown.patch +- Fix CVE-2025-0677 (bsc#1237002) +- Fix CVE-2025-0684 (bsc#1237008) +- Fix CVE-2025-0685 (bsc#1237009) +- Fix CVE-2025-0686 (bsc#1237010) +- Fix CVE-2025-0689 (bsc#1237011) + * 0019-fs-Disable-many-filesystems-under-lockdown.patch +- Fix CVE-2025-1125 (bsc#1237014) +- Fix CVE-2025-0678 (bsc#1237006) + * 0020-fs-Prevent-overflows-when-allocating-memory-for-arra.patch +- Updated to upstream version + * 0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch +- Bump upstream SBAT generation to 5 + +------------------------------------------------------------------- +Thu Feb 13 15:28:50 UTC 2025 - Michael Chang + +- Fix out of memory issue on PowerPC by increasing RMA size (bsc#1236744) + * 0001-powerpc-increase-MIN-RMA-size-for-CAS-negotiation.patch + ------------------------------------------------------------------- Sun Dec 8 10:22:43 UTC 2024 - Michael Chang diff --git a/grub2.spec b/grub2.spec index aa660fc..a58ffa8 100644 --- a/grub2.spec +++ b/grub2.spec @@ -1,7 +1,7 @@ # # spec file for package grub2 # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -22,7 +22,7 @@ %if %{defined sbat_distro} # SBAT metadata %define sbat_generation 1 -%define sbat_generation_grub 4 +%define sbat_generation_grub 5 %else %{error please define sbat_distro, sbat_distro_summary and sbat_distro_url} %endif @@ -416,6 +416,27 @@ Patch234: 0001-cli_lock-Add-build-option-to-block-command-line-inte.patch Patch235: 0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch Patch236: 0001-kern-main-Fix-cmdpath-in-root-directory.patch Patch237: grub2-s390x-secure-execution-support.patch +Patch238: 0001-powerpc-increase-MIN-RMA-size-for-CAS-negotiation.patch +Patch239: 0001-misc-Implement-grub_strlcpy.patch +Patch240: 0002-fs-ufs-Fix-a-heap-OOB-write.patch +Patch241: 0003-fs-hfs-Fix-stack-OOB-write-with-grub_strcpy.patch +Patch242: 0004-fs-tar-Integer-overflow-leads-to-heap-OOB-write.patch +Patch243: 0005-fs-hfsplus-Set-a-grub_errno-if-mount-fails.patch +Patch244: 0006-kern-file-Ensure-file-data-is-set.patch +Patch245: 0007-kern-file-Implement-filesystem-reference-counting.patch +Patch246: 0008-net-Fix-OOB-write-in-grub_net_search_config_file.patch +Patch247: 0009-video-readers-jpeg-Do-not-permit-duplicate-SOF0-mark.patch +Patch248: 0010-commands-extcmd-Missing-check-for-failed-allocation.patch +Patch249: 0011-commands-pgp-Unregister-the-check_signatures-hooks-o.patch +Patch250: 0012-normal-Remove-variables-hooks-on-module-unload.patch +Patch251: 0013-gettext-Remove-variables-hooks-on-module-unload.patch +Patch252: 0014-gettext-Integer-overflow-leads-to-heap-OOB-write-or-.patch +Patch253: 0015-gettext-Integer-overflow-leads-to-heap-OOB-write.patch +Patch254: 0016-commands-read-Fix-an-integer-overflow-when-supplying.patch +Patch255: 0017-commands-minicmd-Block-the-dump-command-in-lockdown-.patch +Patch256: 0018-fs-bfs-Disable-under-lockdown.patch +Patch257: 0019-fs-Disable-many-filesystems-under-lockdown.patch +Patch258: 0020-fs-Prevent-overflows-when-allocating-memory-for-arra.patch %if 0%{?suse_version} <= 1600 Requires: gettext-runtime