From 5264adf6fc1bc574ac1fbd0440c23774f8620242 Mon Sep 17 00:00:00 2001 From: Qiumiao Zhang Date: Mon, 18 Aug 2025 08:02:31 +0000 Subject: [PATCH] backport some patches from upstream Signed-off-by: Qiumiao Zhang --- ...x-NULL-dereference-in-the-knetbsd-te.patch | 35 ++ backport-disk-ldm-Fix-memory-leaks.patch | 483 ++++++++++++++++++ backport-fs-btrfs-Fix-memory-leaks.patch | 44 ++ ...-pointer-dereference-and-possible-in.patch | 45 ++ ...a-number-of-memory-leaks-in-ZFS-code.patch | 243 +++++++++ ...B-menu-gets-stuck-due-to-unserialize.patch | 127 +++++ ...timer-The-GRUB-menu-gets-stuck-due-t.patch | 42 ++ ...nbreak-support-for-nested-partitions.patch | 30 ++ ...port-lib-reloacator-Fix-memory-leaks.patch | 43 ++ ...-loader-i386-linux-Fix-resource-leak.patch | 33 ++ ...ee1275-ofnet-Add-missing-grub_malloc.patch | 34 ++ ...on-t-let-trailing-blank-lines-determ.patch | 67 +++ ...cr-Return-if-redirection-is-disabled.patch | 38 ++ grub.patches | 13 + grub2.spec | 20 +- 15 files changed, 1296 insertions(+), 1 deletion(-) create mode 100644 backport-commands-file-Fix-NULL-dereference-in-the-knetbsd-te.patch create mode 100644 backport-disk-ldm-Fix-memory-leaks.patch create mode 100644 backport-fs-btrfs-Fix-memory-leaks.patch create mode 100644 backport-fs-ntfs-Fix-NULL-pointer-dereference-and-possible-in.patch create mode 100644 backport-fs-zfs-Fix-a-number-of-memory-leaks-in-ZFS-code.patch create mode 100644 backport-i386-tsc-The-GRUB-menu-gets-stuck-due-to-unserialize.patch create mode 100644 backport-kern-i386-tsc_pmtimer-The-GRUB-menu-gets-stuck-due-t.patch create mode 100644 backport-kern-partition-Unbreak-support-for-nested-partitions.patch create mode 100644 backport-lib-reloacator-Fix-memory-leaks.patch create mode 100644 backport-loader-i386-linux-Fix-resource-leak.patch create mode 100644 backport-net-drivers-ieee1275-ofnet-Add-missing-grub_malloc.patch create mode 100644 backport-script-execute-Don-t-let-trailing-blank-lines-determ.patch create mode 100644 backport-term-ns8250-spcr-Return-if-redirection-is-disabled.patch diff --git a/backport-commands-file-Fix-NULL-dereference-in-the-knetbsd-te.patch b/backport-commands-file-Fix-NULL-dereference-in-the-knetbsd-te.patch new file mode 100644 index 0000000..84db90d --- /dev/null +++ b/backport-commands-file-Fix-NULL-dereference-in-the-knetbsd-te.patch @@ -0,0 +1,35 @@ +From 7161e2437dda654c69b930edb2fd18bbfe5c1f05 Mon Sep 17 00:00:00 2001 +From: Lukas Fink +Date: Sun, 5 Jan 2025 02:24:11 -0600 +Subject: [PATCH] commands/file: Fix NULL dereference in the knetbsd tests + +The pointer returned by grub_elf_file() is not checked to verify it is +not NULL before use. A NULL pointer may be returned when the given file +does not have a valid ELF header. + +Fixes: https://savannah.gnu.org/bugs/?61960 + +Signed-off-by: Glenn Washburn +Signed-off-by: Lukas Fink +Reviewed-by: Ross Philipson +Reviewed-by: Daniel Kiper +--- + grub-core/commands/file.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/grub-core/commands/file.c b/grub-core/commands/file.c +index 7c13e976b..19602d757 100644 +--- a/grub-core/commands/file.c ++++ b/grub-core/commands/file.c +@@ -306,6 +306,8 @@ grub_cmd_file (grub_extcmd_context_t ctxt, int argc, char **args) + + elf = grub_elf_file (file, file->name); + ++ if (elf == NULL) ++ break; + if (elf->ehdr.ehdr32.e_type != grub_cpu_to_le16_compile_time (ET_EXEC) + || elf->ehdr.ehdr32.e_ident[EI_DATA] != ELFDATA2LSB) + break; +-- +2.33.0 + diff --git a/backport-disk-ldm-Fix-memory-leaks.patch b/backport-disk-ldm-Fix-memory-leaks.patch new file mode 100644 index 0000000..906b2f1 --- /dev/null +++ b/backport-disk-ldm-Fix-memory-leaks.patch @@ -0,0 +1,483 @@ +From f3f1fcecdce5e8d7099befc3d2c3ae25eb7cc954 Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Thu, 27 Mar 2025 17:56:31 +0000 +Subject: [PATCH] disk/ldm: Fix memory leaks + +Fix memory leaks in make_vg() with new helper functions, free_pv() +and free_lv(). Additionally, correct a check after allocating +comp->segments->nodes that mistakenly checked lv->segments->nodes +instead, likely due to a copy-paste error. + +Fixes: CID 473878 +Fixes: CID 473884 +Fixes: CID 473889 +Fixes: CID 473890 + +Signed-off-by: Lidong Chen +Reviewed-by: Vladimir Serbinenko +Reviewed-by: Daniel Kiper +--- + grub-core/disk/ldm.c | 180 +++++++++++++++++++------------------------ + 1 file changed, 80 insertions(+), 100 deletions(-) + +diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c +index 048e29cd0..0f4f22aaa 100644 +--- a/grub-core/disk/ldm.c ++++ b/grub-core/disk/ldm.c +@@ -179,6 +179,36 @@ gpt_ldm_sector (grub_disk_t dsk) + return sector; + } + ++static void ++free_pv (struct grub_diskfilter_pv *pv) ++{ ++ if (pv == NULL) ++ return; ++ ++ grub_free (pv->internal_id); ++ grub_free (pv->id.uuid); ++ grub_free (pv); ++} ++ ++static void ++free_lv (struct grub_diskfilter_lv *lv) ++{ ++ if (lv == NULL) ++ return; ++ ++ grub_free (lv->internal_id); ++ grub_free (lv->name); ++ grub_free (lv->fullname); ++ if (lv->segments) ++ { ++ unsigned int i; ++ for (i = 0; i < lv->segment_count; i++) ++ grub_free (lv->segments[i].nodes); ++ grub_free (lv->segments); ++ } ++ grub_free (lv); ++} ++ + static struct grub_diskfilter_vg * + make_vg (grub_disk_t disk, + const struct grub_ldm_label *label) +@@ -196,12 +226,8 @@ make_vg (grub_disk_t disk, + vg->name = grub_malloc (LDM_NAME_STRLEN + 1); + vg->uuid = grub_malloc (LDM_GUID_STRLEN + 1); + if (! vg->uuid || !vg->name) +- { +- grub_free (vg->uuid); +- grub_free (vg->name); +- grub_free (vg); +- return NULL; +- } ++ goto fail1; ++ + grub_memcpy (vg->uuid, label->group_guid, LDM_GUID_STRLEN); + grub_memcpy (vg->name, label->group_name, LDM_NAME_STRLEN); + vg->name[LDM_NAME_STRLEN] = 0; +@@ -261,7 +287,7 @@ make_vg (grub_disk_t disk, + pv->internal_id = grub_malloc (sz); + if (!pv->internal_id) + { +- grub_free (pv); ++ free_pv (pv); + goto fail2; + } + grub_memcpy (pv->internal_id, ptr, (grub_size_t) ptr[0] + 1); +@@ -271,7 +297,7 @@ make_vg (grub_disk_t disk, + if (ptr + *ptr + 1 >= vblk[i].dynamic + + sizeof (vblk[i].dynamic)) + { +- grub_free (pv); ++ free_pv (pv); + goto fail2; + } + /* ptr = name. */ +@@ -279,23 +305,21 @@ make_vg (grub_disk_t disk, + if (ptr + *ptr + 1 + >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) + { +- grub_free (pv); ++ free_pv (pv); + goto fail2; + } + pv->id.uuidlen = *ptr; + + if (grub_add (pv->id.uuidlen, 1, &sz)) + { +- grub_free (pv->internal_id); +- grub_free (pv); ++ free_pv (pv); + goto fail2; + } + + pv->id.uuid = grub_malloc (sz); + if (pv->id.uuid == NULL) + { +- grub_free (pv->internal_id); +- grub_free (pv); ++ free_pv (pv); + goto fail2; + } + grub_memcpy (pv->id.uuid, ptr + 1, pv->id.uuidlen); +@@ -343,7 +367,7 @@ make_vg (grub_disk_t disk, + lv->segments = grub_zalloc (sizeof (*lv->segments)); + if (!lv->segments) + { +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + lv->segments->start_extent = 0; +@@ -354,26 +378,25 @@ make_vg (grub_disk_t disk, + sizeof (*lv->segments->nodes)); + if (!lv->segments->nodes) + { +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + ptr = vblk[i].dynamic; + if (ptr + *ptr + 1 >= vblk[i].dynamic + + sizeof (vblk[i].dynamic)) + { +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + if (grub_add (ptr[0], 2, &sz)) + { +- grub_free (lv->segments); +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + lv->internal_id = grub_malloc (sz); + if (!lv->internal_id) + { +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + grub_memcpy (lv->internal_id, ptr, ptr[0] + 1); +@@ -383,20 +406,18 @@ make_vg (grub_disk_t disk, + if (ptr + *ptr + 1 >= vblk[i].dynamic + + sizeof (vblk[i].dynamic)) + { +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + if (grub_add (*ptr, 1, &sz)) + { +- grub_free (lv->internal_id); +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + lv->name = grub_malloc (sz); + if (!lv->name) + { +- grub_free (lv->internal_id); +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + grub_memcpy (lv->name, ptr + 1, *ptr); +@@ -405,36 +426,28 @@ make_vg (grub_disk_t disk, + vg->uuid, lv->name); + if (!lv->fullname) + { +- grub_free (lv->internal_id); +- grub_free (lv->name); +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + ptr += *ptr + 1; + if (ptr + *ptr + 1 + >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) + { +- grub_free (lv->internal_id); +- grub_free (lv->name); +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + /* ptr = volume type. */ + ptr += *ptr + 1; + if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) + { +- grub_free (lv->internal_id); +- grub_free (lv->name); +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + /* ptr = flags. */ + ptr += *ptr + 1; + if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) + { +- grub_free (lv->internal_id); +- grub_free (lv->name); +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + +@@ -443,17 +456,13 @@ make_vg (grub_disk_t disk, + /* ptr = number of children. */ + if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) + { +- grub_free (lv->internal_id); +- grub_free (lv->name); +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + ptr += *ptr + 1; + if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) + { +- grub_free (lv->internal_id); +- grub_free (lv->name); +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + +@@ -463,9 +472,7 @@ make_vg (grub_disk_t disk, + || ptr + *ptr + 1>= vblk[i].dynamic + + sizeof (vblk[i].dynamic)) + { +- grub_free (lv->internal_id); +- grub_free (lv->name); +- grub_free (lv); ++ free_lv (lv); + goto fail2; + } + lv->size = read_int (ptr + 1, *ptr); +@@ -515,18 +522,18 @@ make_vg (grub_disk_t disk, + ptr = vblk[i].dynamic; + if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) + { +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + if (grub_add (ptr[0], 2, &sz)) + { +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + comp->internal_id = grub_malloc (sz); + if (!comp->internal_id) + { +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + grub_memcpy (comp->internal_id, ptr, ptr[0] + 1); +@@ -535,16 +542,14 @@ make_vg (grub_disk_t disk, + ptr += *ptr + 1; + if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) + { +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + /* ptr = name. */ + ptr += *ptr + 1; + if (ptr + *ptr + 1 >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) + { +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + /* ptr = state. */ +@@ -554,8 +559,7 @@ make_vg (grub_disk_t disk, + ptr += 4; + if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) + { +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + +@@ -563,16 +567,14 @@ make_vg (grub_disk_t disk, + ptr += *ptr + 1; + if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)) + { +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + ptr += 8 + 8; + if (ptr + *ptr + 1 >= vblk[i].dynamic + + sizeof (vblk[i].dynamic)) + { +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + for (lv = vg->lvs; lv; lv = lv->next) +@@ -583,8 +585,7 @@ make_vg (grub_disk_t disk, + } + if (!lv) + { +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + continue; + } + comp->size = lv->size; +@@ -596,8 +597,7 @@ make_vg (grub_disk_t disk, + sizeof (*comp->segments)); + if (!comp->segments) + { +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + } +@@ -608,8 +608,7 @@ make_vg (grub_disk_t disk, + comp->segments = grub_malloc (sizeof (*comp->segments)); + if (!comp->segments) + { +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + comp->segments->start_extent = 0; +@@ -624,27 +623,21 @@ make_vg (grub_disk_t disk, + } + else + { +- grub_free (comp->segments); +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + ptr += *ptr + 1; + ptr++; + if (!(vblk[i].flags & 0x10)) + { +- grub_free (comp->segments); +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic) + || ptr + *ptr + 1 >= vblk[i].dynamic + + sizeof (vblk[i].dynamic)) + { +- grub_free (comp->segments); +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + comp->segments->stripe_size = read_int (ptr + 1, *ptr); +@@ -652,20 +645,16 @@ make_vg (grub_disk_t disk, + if (ptr + *ptr + 1 >= vblk[i].dynamic + + sizeof (vblk[i].dynamic)) + { +- grub_free (comp->segments); +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + comp->segments->node_count = read_int (ptr + 1, *ptr); + comp->segments->node_alloc = comp->segments->node_count; + comp->segments->nodes = grub_calloc (comp->segments->node_alloc, + sizeof (*comp->segments->nodes)); +- if (!lv->segments->nodes) ++ if (comp->segments->nodes == NULL) + { +- grub_free (comp->segments); +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + } +@@ -677,20 +666,14 @@ make_vg (grub_disk_t disk, + if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) || + grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz)) + { +- grub_free (comp->segments->nodes); +- grub_free (comp->segments); +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + + t = grub_realloc (lv->segments->nodes, sz); + if (!t) + { +- grub_free (comp->segments->nodes); +- grub_free (comp->segments); +- grub_free (comp->internal_id); +- grub_free (comp); ++ free_lv (comp); + goto fail2; + } + lv->segments->nodes = t; +@@ -830,7 +813,10 @@ make_vg (grub_disk_t disk, + comp->segments[comp->segment_count].nodes + = grub_malloc (sizeof (*comp->segments[comp->segment_count].nodes)); + if (!comp->segments[comp->segment_count].nodes) +- goto fail2; ++ { ++ grub_free (comp->segments); ++ goto fail2; ++ } + comp->segments[comp->segment_count].nodes[0] = part; + comp->segment_count++; + } +@@ -845,25 +831,19 @@ make_vg (grub_disk_t disk, + struct grub_diskfilter_pv *pv, *next_pv; + for (lv = vg->lvs; lv; lv = next_lv) + { +- unsigned i; +- for (i = 0; i < lv->segment_count; i++) +- grub_free (lv->segments[i].nodes); +- + next_lv = lv->next; +- grub_free (lv->segments); +- grub_free (lv->internal_id); +- grub_free (lv->name); +- grub_free (lv->fullname); +- grub_free (lv); ++ free_lv (lv); ++ + } + for (pv = vg->pvs; pv; pv = next_pv) + { + next_pv = pv->next; +- grub_free (pv->id.uuid); +- grub_free (pv); ++ free_pv (pv); + } + } ++ fail1: + grub_free (vg->uuid); ++ grub_free (vg->name); + grub_free (vg); + return NULL; + } +-- +2.33.0 + diff --git a/backport-fs-btrfs-Fix-memory-leaks.patch b/backport-fs-btrfs-Fix-memory-leaks.patch new file mode 100644 index 0000000..964b3d0 --- /dev/null +++ b/backport-fs-btrfs-Fix-memory-leaks.patch @@ -0,0 +1,44 @@ +From f94d257e8c983e6c3f4a7f5ce8a45f5cd7299f04 Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Thu, 27 Mar 2025 17:56:34 +0000 +Subject: [PATCH] fs/btrfs: Fix memory leaks + +Fix memory leaks in grub_btrfs_extent_read() and grub_btrfs_dir(). + +Fixes: CID 473842 +Fixes: CID 473871 + +Signed-off-by: Lidong Chen +Reviewed-by: Vladimir Serbinenko +Reviewed-by: Daniel Kiper +--- + grub-core/fs/btrfs.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c +index 9c1e925c9..7bf8d922f 100644 +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -1538,7 +1538,10 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data, + err = lower_bound (data, &key_in, &key_out, tree, + &elemaddr, &elemsize, &desc, 0); + if (err) +- return -1; ++ { ++ grub_free (desc.data); ++ return -1; ++ } + if (key_out.object_id != ino + || key_out.type != GRUB_BTRFS_ITEM_TYPE_EXTENT_ITEM) + { +@@ -2115,6 +2118,7 @@ grub_btrfs_dir (grub_device_t device, const char *path, + if (err) + { + grub_btrfs_unmount (data); ++ grub_free (desc.data); + return err; + } + if (key_out.type != GRUB_BTRFS_ITEM_TYPE_DIR_ITEM +-- +2.33.0 + diff --git a/backport-fs-ntfs-Fix-NULL-pointer-dereference-and-possible-in.patch b/backport-fs-ntfs-Fix-NULL-pointer-dereference-and-possible-in.patch new file mode 100644 index 0000000..7181d71 --- /dev/null +++ b/backport-fs-ntfs-Fix-NULL-pointer-dereference-and-possible-in.patch @@ -0,0 +1,45 @@ +From aae2ea619e0f09c353fd6929910f925c92a412c0 Mon Sep 17 00:00:00 2001 +From: Andrew Hamilton +Date: Thu, 20 Mar 2025 18:28:00 -0500 +Subject: [PATCH] fs/ntfs: Fix NULL pointer dereference and possible infinite + loop + +A regression was introduced recently as a part of the series of +filesystem related patches to address some CVEs found in GRUB. + +This issue may cause either an infinite loop at startup when +accessing certain valid NTFS filesystems, or may cause a crash +due to a NULL pointer dereference on systems where NULL address +is invalid (such as may happen when calling grub-mount from +the operating system level). + +Correct this issue by checking that at->attr_cur is within bounds +inside find_attr(). + +Fixes: https://savannah.gnu.org/bugs/?66855 +Fixes: aff263187 (fs/ntfs: Fix out-of-bounds read) + +Signed-off-by: B Horn +Signed-off-by: Andrew Hamilton +Reviewed-by: Daniel Kiper +--- + grub-core/fs/ntfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c +index 960833a34..b3117bf92 100644 +--- a/grub-core/fs/ntfs.c ++++ b/grub-core/fs/ntfs.c +@@ -387,7 +387,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr) + } + at->attr_cur = at->attr_nxt; + mft_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR); +- while (at->attr_cur < mft_end && *at->attr_cur != 0xFF) ++ while (at->attr_cur >= at->mft->buf && at->attr_cur < mft_end && *at->attr_cur != 0xFF) + { + at->attr_nxt = next_attribute (at->attr_cur, at->end); + if (*at->attr_cur == GRUB_NTFS_AT_ATTRIBUTE_LIST) +-- +2.33.0 + diff --git a/backport-fs-zfs-Fix-a-number-of-memory-leaks-in-ZFS-code.patch b/backport-fs-zfs-Fix-a-number-of-memory-leaks-in-ZFS-code.patch new file mode 100644 index 0000000..e9368bc --- /dev/null +++ b/backport-fs-zfs-Fix-a-number-of-memory-leaks-in-ZFS-code.patch @@ -0,0 +1,243 @@ +From b66c6f9182fce873d906bc9871c649af38e35b53 Mon Sep 17 00:00:00 2001 +From: Stuart Hayes +Date: Mon, 10 Mar 2025 11:23:59 -0500 +Subject: [PATCH] fs/zfs: Fix a number of memory leaks in ZFS code + +Without this fix the GRUB failed to boot linux with "out of memory" after +trying to run a "search --fs-uuid..." on a system that has 7 ZFS pools +across about 80 drives. + +Signed-off-by: Stuart Hayes +Reviewed-by: Vladimir Serbinenko +Reviewed-by: Daniel Kiper +--- + grub-core/fs/zfs/zfs.c | 43 +++++++++++++++++++++++++++++++++----- + grub-core/fs/zfs/zfsinfo.c | 5 ++++- + 2 files changed, 42 insertions(+), 6 deletions(-) + +diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c +index 376042631..bff9d0208 100644 +--- a/grub-core/fs/zfs/zfs.c ++++ b/grub-core/fs/zfs/zfs.c +@@ -1057,8 +1057,10 @@ check_pool_label (struct grub_zfs_data *data, + ZIO_SET_CHECKSUM(&emptycksum, diskdesc->vdev_phys_sector << 9, 0, 0, 0); + err = zio_checksum_verify (emptycksum, ZIO_CHECKSUM_LABEL, endian, + nvlist, VDEV_PHYS_SIZE); +- if (err) ++ if (err) { ++ grub_free (nvlist); + return err; ++ } + + grub_dprintf ("zfs", "check 2 passed\n"); + +@@ -1144,8 +1146,10 @@ check_pool_label (struct grub_zfs_data *data, + if (original) + data->guid = poolguid; + +- if (data->guid != poolguid) ++ if (data->guid != poolguid) { ++ grub_free (nvlist); + return grub_error (GRUB_ERR_BAD_FS, "another zpool"); ++ } + + { + char *nv; +@@ -1186,9 +1190,12 @@ check_pool_label (struct grub_zfs_data *data, + { + grub_dprintf("zfs","feature missing in check_pool_label:%s\n",name); + err= grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET," check_pool_label missing feature '%s' for read",name); ++ grub_free(features); ++ grub_free(nvlist); + return err; + } + } ++ grub_free(features); + } + grub_dprintf ("zfs", "check 12 passed (feature flags)\n"); + grub_free (nvlist); +@@ -2601,6 +2608,7 @@ zap_lookup (dnode_end_t * zap_dnode, const char *name, grub_uint64_t *val, + return err; + } + ++ grub_free (zapbuf); + return grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); + } + +@@ -2671,6 +2679,7 @@ zap_iterate_u64 (dnode_end_t * zap_dnode, + grub_free (zapbuf); + return ret; + } ++ grub_free (zapbuf); + grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); + return 0; + } +@@ -2701,6 +2710,7 @@ zap_iterate (dnode_end_t * zap_dnode, + if (block_type == ZBT_MICRO) + { + grub_error (GRUB_ERR_BAD_FS, "micro ZAP where FAT ZAP expected"); ++ grub_free (zapbuf); + return 0; + } + if (block_type == ZBT_HEADER) +@@ -2712,6 +2722,7 @@ zap_iterate (dnode_end_t * zap_dnode, + grub_free (zapbuf); + return ret; + } ++ grub_free (zapbuf); + grub_error (GRUB_ERR_BAD_FS, "unknown ZAP type"); + return 0; + } +@@ -2785,6 +2796,9 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type, + } + + grub_memmove (&(buf->dn), (dnode_phys_t *) dnbuf + idx, DNODE_SIZE); ++ if (data->dnode_buf == 0) ++ /* dnbuf not used anymore if data->dnode_mdn malloc failed */ ++ grub_free (dnbuf); + buf->endian = endian; + if (type && buf->dn.dn_type != type) + return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type"); +@@ -3436,6 +3450,8 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, + if (err) + { + grub_dprintf ("zfs", "failed here\n"); ++ grub_free (fsname); ++ grub_free (snapname); + return err; + } + +@@ -3472,8 +3488,11 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol, + if (!err) + err = dnode_get (&(data->mos), headobj, 0, + &subvol->mdn, data); +- if (!err && subvol->mdn.dn.dn_type != DMU_OT_DSL_DATASET && subvol->mdn.dn.dn_bonustype != DMU_OT_DSL_DATASET) ++ if (!err && subvol->mdn.dn.dn_type != DMU_OT_DSL_DATASET && subvol->mdn.dn.dn_bonustype != DMU_OT_DSL_DATASET) { ++ grub_free (fsname); ++ grub_free (snapname); + return grub_error(GRUB_ERR_BAD_FS, "incorrect dataset dnode type"); ++ } + + if (err) + { +@@ -3952,6 +3971,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) + { + void *sahdrp; + int hdrsize; ++ bool free_sahdrp = false; + + if (data->dnode.dn.dn_bonuslen != 0) + { +@@ -3964,6 +3984,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) + err = zio_read (bp, data->dnode.endian, &sahdrp, NULL, data); + if (err) + return err; ++ free_sahdrp = true; + } + else + { +@@ -3972,6 +3993,8 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename) + + hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); + file->size = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET), data->dnode.endian); ++ if (free_sahdrp) ++ grub_free(sahdrp); + } + else if (data->dnode.dn.dn_bonustype == DMU_OT_ZNODE) + { +@@ -4157,6 +4180,7 @@ fill_fs_info (struct grub_dirhook_info *info, + { + void *sahdrp; + int hdrsize; ++ bool free_sahdrp = false; + + if (dn.dn.dn_bonuslen != 0) + { +@@ -4169,6 +4193,7 @@ fill_fs_info (struct grub_dirhook_info *info, + err = zio_read (bp, dn.endian, &sahdrp, NULL, data); + if (err) + return err; ++ free_sahdrp = true; + } + else + { +@@ -4179,6 +4204,8 @@ fill_fs_info (struct grub_dirhook_info *info, + hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp)); + info->mtimeset = 1; + info->mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); ++ if (free_sahdrp) ++ grub_free (sahdrp); + } + + if (dn.dn.dn_bonustype == DMU_OT_ZNODE) +@@ -4210,6 +4237,7 @@ iterate_zap (const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx) + { + void *sahdrp; + int hdrsize; ++ bool free_sahdrp = false; + + if (dn.dn.dn_bonuslen != 0) + { +@@ -4225,6 +4253,7 @@ iterate_zap (const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx) + grub_print_error (); + return 0; + } ++ free_sahdrp = true; + } + else + { +@@ -4237,6 +4266,8 @@ iterate_zap (const char *name, grub_uint64_t val, struct grub_zfs_dir_ctx *ctx) + info.mtimeset = 1; + info.mtime = grub_zfs_to_cpu64 (grub_get_unaligned64 ((char *) sahdrp + hdrsize + SA_MTIME_OFFSET), dn.endian); + info.case_insensitive = ctx->data->subvol.case_insensitive; ++ if (free_sahdrp) ++ grub_free (sahdrp); + } + + if (dn.dn.dn_bonustype == DMU_OT_ZNODE) +@@ -4448,7 +4479,7 @@ check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct gru + dnode_end_t dn,mosmdn; + mzap_phys_t* mzp; + grub_zfs_endian_t endianzap; +- int size; ++ int size, ret; + grub_memmove(&(mosmdn.dn),mosmdn_phys,sizeof(dnode_phys_t)); + mosmdn.endian=endian; + errnum = dnode_get(&mosmdn, DMU_POOL_DIRECTORY_OBJECT, +@@ -4474,7 +4505,9 @@ check_mos_features(dnode_phys_t *mosmdn_phys,grub_zfs_endian_t endian,struct gru + return errnum; + + size = grub_zfs_to_cpu16 (dn.dn.dn_datablkszsec, dn.endian) << SPA_MINBLOCKSHIFT; +- return mzap_iterate (mzp,endianzap, size, check_feature,NULL); ++ ret = mzap_iterate (mzp,endianzap, size, check_feature,NULL); ++ grub_free(mzp); ++ return ret; + } + + +diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c +index c8a28acf5..31d767bbd 100644 +--- a/grub-core/fs/zfs/zfsinfo.c ++++ b/grub-core/fs/zfs/zfsinfo.c +@@ -379,14 +379,17 @@ grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc, + + grub_device_close (dev); + +- if (err) ++ if (err) { ++ grub_free (nvlist); + return err; ++ } + + poolname = grub_zfs_nvlist_lookup_string (nvlist, ZPOOL_CONFIG_POOL_NAME); + if (!poolname) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_FS, "No poolname found"); ++ grub_free (nvlist); + return grub_errno; + } + +-- +2.33.0 + diff --git a/backport-i386-tsc-The-GRUB-menu-gets-stuck-due-to-unserialize.patch b/backport-i386-tsc-The-GRUB-menu-gets-stuck-due-to-unserialize.patch new file mode 100644 index 0000000..f817976 --- /dev/null +++ b/backport-i386-tsc-The-GRUB-menu-gets-stuck-due-to-unserialize.patch @@ -0,0 +1,127 @@ +From 531750f7bfc475332b2046dd516bab582ba7decf Mon Sep 17 00:00:00 2001 +From: Duan Yayong +Date: Mon, 9 Dec 2024 14:48:32 +0800 +Subject: [PATCH] i386/tsc: The GRUB menu gets stuck due to unserialized rdtsc +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch is used to fix GRUB menu gets stuck in server AC +poweron/poweroff stress test of x86_64, which is reproduced with +1/200 ratio. The root cause analysis as below: + +Q: What's the code logic? + +A: The grub_tsc_init() function will init tsc by setting grub_tsc_rate, + which call stack is: + + grub_tsc_init() -> grub_tsc_calibrate_from_pmtimer() -> grub_divmod64() + + Among, grub_divmod64() function needs tsc_diff as the second parameter. + In grub_pmtimer_wait_count_tsc(), we will call grub_get_tsc() function + to get time stamp counter value to assign to start_tsc variable, and + get into while (1) loop space to get end_tsc variable value with same + function, after 3580 ticks, return "end_tsc - start_tsc". Actually, + rdtsc instruction will be called in grub_get_tsc, but rdtsc instruction + is not reliable (for the reason see the next question), which will cause + tsc_diff to be a very big number larger than (1UL << 32) or a negative + number, so that grub_tsc_rate will be zero. When run_menu() function is + startup, and calls grub_tsc_get_time_ms() function to get current time + to check if timeout time reach, at this time, grub_tsc_get_time_ms() + function will return zero due to zero grub_tsc_rate variable, then GRUB + menu gets stuck... + +Q: What's the difference between rdtsc and rdtscp instructions in x86_64 + architecture? Here is more explanations from Intel® 64 and IA-32 + Architectures Software Developer’s Manual Volume 2B (December 2024): + https://cdrdv2.intel.com/v1/dl/getContent/671241 + +A: In page 4-558 -> RDTSC—Read Time-Stamp Counter: + The RDTSC instruction is not a serializing instruction. It does not + necessarily wait until all previous instructions have been executed + before reading the counter. Similarly, subsequent instructions may + begin execution before the read operation is performed. The following + items may guide software seeking to order executions of RDTSC: + - If software requires RDTSC to be executed only after all previous + instructions have executed and all previous loads are globally + visible, it can execute LFENCE immediately before RDTSC. + - If software requires RDTSC to be executed only after all previous + instructions have executed and all previous loads and stores are + globally visible, it can execute the sequence MFENCE;LFENCE + immediately before RDTSC. + - If software requires RDTSC to be executed prior to execution of any + subsequent instruction (including any memory accesses), it can execute + the sequence LFENCE immediately after RDTSC. + +A: In page 4-560 -> RDTSCP—Read Time-Stamp Counter and Processor ID: + The RDTSCP instruction is not a serializing instruction, but it does wait + until all previous instructions have executed and all previous loads are + globally visible. But it does not wait for previous stores to be globally + visible, and subsequent instructions may begin execution before the read + operation is performed. The following items may guide software seeking to + order executions of RDTSCP: + - If software requires RDTSCP to be executed only after all previous + stores are globally visible, it can execute MFENCE immediately before + RDTSCP. + - If software requires RDTSCP to be executed prior to execution of any + subsequent instruction (including any memory accesses), it can execute + LFENCE immediately after RDTSCP. + +Q: Why there is a cpuid serializing instruction before rdtsc instruction, + but "grub_get_tsc" still cannot work as expect? + +A: From Intel® 64 and IA-32 Architectures Software Developer's Manual + Volume 2A: Instruction Set Reference, A-L (December 2024): + https://cdrdv2.intel.com/v1/dl/getContent/671199 + + In page 3-222 -> CPUID—CPU Identification: + CPUID can be executed at any privilege level to serialize instruction execution. + Serializing instruction execution guarantees that any modifications to flags, + registers, and memory for previous instructions are completed before + the next instruction is fetched and executed. + + So we only kept the instruction rdtsc and its previous instruction in order + currently. But it is still out-of-order possibility between rdtsc instruction + and its subsequent instruction. + +Q: Why do we do this fix? + +A: In the one hand, add cpuid instruction after rdtsc instruction to make sure + rdtsc instruction to be executed prior to execution of any subsequent instruction, + about serializing execution that all previous instructions have been executed + before rdtsc, there is a cpuid usage in original code. In the other hand, using + cpuid instruction rather than lfence can make sure a forward compatibility for + previous HW. + + Base this fix, we did 1500 cycles power on/off stress test, and did not reproduce + this issue again. + +Fixes: https://savannah.gnu.org/bugs/?66257 + +Signed-off-by: Duan Yayong +Signed-off-by: Li Yongqiang +Signed-off-by: Sun Ming +Reviewed-by: Daniel Kiper +--- + include/grub/i386/tsc.h | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/include/grub/i386/tsc.h b/include/grub/i386/tsc.h +index 947e62fa1..3c96d3e0b 100644 +--- a/include/grub/i386/tsc.h ++++ b/include/grub/i386/tsc.h +@@ -47,6 +47,11 @@ grub_get_tsc (void) + /* Read TSC value. We cannot use "=A", since this would use + %rax on x86_64. */ + asm volatile ("rdtsc":"=a" (lo), "=d" (hi)); ++ /* ++ * Run cpuid after rdtsc instruction to ensure rdtsc is executed before ++ * subsequent instruction. ++ */ ++ grub_cpuid (0, a, b, c, d); + + return (((grub_uint64_t) hi) << 32) | lo; + } +-- +2.33.0 + diff --git a/backport-kern-i386-tsc_pmtimer-The-GRUB-menu-gets-stuck-due-t.patch b/backport-kern-i386-tsc_pmtimer-The-GRUB-menu-gets-stuck-due-t.patch new file mode 100644 index 0000000..a40cec6 --- /dev/null +++ b/backport-kern-i386-tsc_pmtimer-The-GRUB-menu-gets-stuck-due-t.patch @@ -0,0 +1,42 @@ +From f2a1f66e721d2231c3f7d80733c33cd808f0155d Mon Sep 17 00:00:00 2001 +From: Duan Yayong +Date: Thu, 28 Nov 2024 11:48:26 +0800 +Subject: [PATCH] kern/i386/tsc_pmtimer: The GRUB menu gets stuck due to failed + calibration + +The grub_divmod64() may return 0 but grub_tsc_calibrate_from_pmtimer() +still returns 1 saying calibration succeeded. Of course it is not true. +So, return 0 when grub_divmod64() returns 0. This way other calibration +functions can be called subsequently. + +Signed-off-by: Duan Yayong +Signed-off-by: Li Yongqiang +Signed-off-by: Sun Ming +Reviewed-by: Daniel Kiper +--- + grub-core/kern/i386/tsc_pmtimer.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/grub-core/kern/i386/tsc_pmtimer.c b/grub-core/kern/i386/tsc_pmtimer.c +index 5c03c510a..dd044590d 100644 +--- a/grub-core/kern/i386/tsc_pmtimer.c ++++ b/grub-core/kern/i386/tsc_pmtimer.c +@@ -143,5 +143,15 @@ grub_tsc_calibrate_from_pmtimer (void) + if (tsc_diff == 0) + return 0; + grub_tsc_rate = grub_divmod64 ((1ULL << 32), tsc_diff, 0); ++ /* ++ * Specifically, when the tsc_diff (end_tsc - start_tsc) is greater than (1ULL << 32), ++ * the result of grub_divmod64() becomes zero, causing grub_tsc_rate to always be zero. ++ * As a result, grub_tsc_get_time_ms() consistently returns zero, and the GRUB menu ++ * countdown gets stuck. To resolve this, we return 0 to proceed to the next calibration ++ * function when grub_tsc_rate is zero. ++ */ ++ if (grub_tsc_rate == 0) ++ return 0; ++ + return 1; + } +-- +2.33.0 + diff --git a/backport-kern-partition-Unbreak-support-for-nested-partitions.patch b/backport-kern-partition-Unbreak-support-for-nested-partitions.patch new file mode 100644 index 0000000..5e535f6 --- /dev/null +++ b/backport-kern-partition-Unbreak-support-for-nested-partitions.patch @@ -0,0 +1,30 @@ +From ee27f07a650d13f66ba7b867de3b39ddeb3631ec Mon Sep 17 00:00:00 2001 +From: Vladimir Serbinenko +Date: Mon, 3 Mar 2025 00:02:21 +0300 +Subject: [PATCH] kern/partition: Unbreak support for nested partitions + +When using syntax "hd0,gtp3,dfly1" then ptr points to trailing part, ",dfly1". +So, it's improper to consider it as an invalid partition. + +Signed-off-by: Vladimir Serbinenko +Reviewed-by: Daniel Kiper +--- + grub-core/kern/partition.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c +index c6a578cf4..3b128e6d2 100644 +--- a/grub-core/kern/partition.c ++++ b/grub-core/kern/partition.c +@@ -134,7 +134,7 @@ grub_partition_probe (struct grub_disk *disk, const char *str) + partname_end = ptr; + + num = grub_strtoul (ptr, &ptr, 0); +- if (*ptr != '\0' || num == 0 || num > GRUB_INT_MAX) ++ if (num == 0 || num > GRUB_INT_MAX) + { + grub_error (GRUB_ERR_BAD_NUMBER, N_("invalid partition number")); + return 0; +-- +2.33.0 + diff --git a/backport-lib-reloacator-Fix-memory-leaks.patch b/backport-lib-reloacator-Fix-memory-leaks.patch new file mode 100644 index 0000000..7ae8c1d --- /dev/null +++ b/backport-lib-reloacator-Fix-memory-leaks.patch @@ -0,0 +1,43 @@ +From 1d005944754b7298b6df3debddb6abae22745265 Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Thu, 27 Mar 2025 17:56:32 +0000 +Subject: [PATCH] lib/reloacator: Fix memory leaks + +Fix memory leaks in grub_relocator_alloc_chunk_align(). + +Fixes: CID 473844 + +Signed-off-by: Lidong Chen +Reviewed-by: Vladimir Serbinenko +Reviewed-by: Daniel Kiper +--- + grub-core/lib/relocator.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/grub-core/lib/relocator.c b/grub-core/lib/relocator.c +index e0478ae5b..3306a1bb7 100644 +--- a/grub-core/lib/relocator.c ++++ b/grub-core/lib/relocator.c +@@ -1440,6 +1440,7 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, + break; + } + ++ grub_free (ctx.chunk); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + } + while (0); +@@ -1456,7 +1457,10 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, + grub_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx); + #endif + if (!ctx.found) +- return grub_error (GRUB_ERR_BAD_OS, "couldn't find suitable memory target"); ++ { ++ grub_free (ctx.chunk); ++ return grub_error (GRUB_ERR_BAD_OS, "couldn't find suitable memory target"); ++ } + } + while (1) + { +-- +2.33.0 + diff --git a/backport-loader-i386-linux-Fix-resource-leak.patch b/backport-loader-i386-linux-Fix-resource-leak.patch new file mode 100644 index 0000000..a59f8e7 --- /dev/null +++ b/backport-loader-i386-linux-Fix-resource-leak.patch @@ -0,0 +1,33 @@ +From 81146fb6238f5202fada90f0da49ba3580b944c2 Mon Sep 17 00:00:00 2001 +From: Lidong Chen +Date: Thu, 27 Mar 2025 17:56:33 +0000 +Subject: [PATCH] loader/i386/linux: Fix resource leak + +In grub_cmd_initrd(), initrd_ctx is allocated before calling +grub_relocator_alloc_chunk_align(). When that function fails, +initrd_ctx should be freed before exiting grub_cmd_initrd(). + +Fixes: CID 473852 + +Signed-off-by: Lidong Chen +Reviewed-by: Daniel Kiper +--- + grub-core/loader/i386/linux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c +index b7c1e057e..4b26cd816 100644 +--- a/grub-core/loader/i386/linux.c ++++ b/grub-core/loader/i386/linux.c +@@ -1128,7 +1128,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + GRUB_RELOCATOR_PREFERENCE_HIGH, + 1); + if (err) +- return err; ++ goto fail; + initrd_mem = get_virtual_current_address (ch); + initrd_mem_target = get_physical_target_address (ch); + } +-- +2.33.0 + diff --git a/backport-net-drivers-ieee1275-ofnet-Add-missing-grub_malloc.patch b/backport-net-drivers-ieee1275-ofnet-Add-missing-grub_malloc.patch new file mode 100644 index 0000000..b1b4b55 --- /dev/null +++ b/backport-net-drivers-ieee1275-ofnet-Add-missing-grub_malloc.patch @@ -0,0 +1,34 @@ +From 3b25e494d47e7a728e7ce6264b10f2aa1063f9c7 Mon Sep 17 00:00:00 2001 +From: Nicolas Frayer +Date: Wed, 19 Mar 2025 17:39:41 +0100 +Subject: [PATCH] net/drivers/ieee1275/ofnet: Add missing grub_malloc() + +The grub_malloc() has been inadvertently removed from the code after it +has been modified to use safe math functions. + +Fixes: 4beeff8a (net: Use safe math macros to prevent overflows) + +Signed-off-by: Nicolas Frayer +Tested-by: Marta Lewandowska +Reviewed-by: Daniel Kiper +--- + grub-core/net/drivers/ieee1275/ofnet.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c +index 3e1b9094e..e5be362a9 100644 +--- a/grub-core/net/drivers/ieee1275/ofnet.c ++++ b/grub-core/net/drivers/ieee1275/ofnet.c +@@ -463,6 +463,9 @@ search_net_devices (struct grub_ieee1275_devalias *alias) + return 0; + } + } ++ ++ ofdata->path = grub_malloc (sz); ++ + if (!ofdata->path) + { + grub_print_error (); +-- +2.33.0 + diff --git a/backport-script-execute-Don-t-let-trailing-blank-lines-determ.patch b/backport-script-execute-Don-t-let-trailing-blank-lines-determ.patch new file mode 100644 index 0000000..4cf1593 --- /dev/null +++ b/backport-script-execute-Don-t-let-trailing-blank-lines-determ.patch @@ -0,0 +1,67 @@ +From 187338f1ac5e6f2a567f0799e5f291c48771d335 Mon Sep 17 00:00:00 2001 +From: James Le Cuirot +Date: Mon, 30 Dec 2024 10:52:23 +0000 +Subject: [PATCH] script/execute: Don't let trailing blank lines determine the + return code + +The grub_script_execute_sourcecode() parses and executes code one line +at a time, updating the return code each time because only the last line +determines the final status. However, trailing new lines were also +executed, masking any failure on the previous line. Fix this by only +trying to execute the command when there is actually one present. + +This has presumably never been noticed because this code is not used by +regular functions, only in special cases like eval and menu entries. The +latter generally don't return at all, having booted an OS. When failing +to boot, upstream GRUB triggers the fallback mechanism regardless of the +return code. + +We noticed the problem while using Red Hat's patches, which change this +behaviour to take account of the return code. In that case, a failure +takes you back to the menu rather than triggering a fallback. + +Signed-off-by: James Le Cuirot +Reviewed-by: Daniel Kiper +--- + grub-core/script/execute.c | 5 ++++- + tests/grub_script_eval.in | 10 +++++++++- + 2 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c +index a86e0051f..da99dfa05 100644 +--- a/grub-core/script/execute.c ++++ b/grub-core/script/execute.c +@@ -914,7 +914,10 @@ grub_script_execute_sourcecode (const char *source) + break; + } + +- ret = grub_script_execute (parsed_script); ++ /* Don't let trailing blank lines determine the return code. */ ++ if (parsed_script->cmd) ++ ret = grub_script_execute (parsed_script); ++ + grub_script_free (parsed_script); + grub_free (line); + } +diff --git a/tests/grub_script_eval.in b/tests/grub_script_eval.in +index c97b78d77..9c6211042 100644 +--- a/tests/grub_script_eval.in ++++ b/tests/grub_script_eval.in +@@ -3,4 +3,12 @@ + eval echo "Hello world" + valname=tst + eval $valname=hi +-echo $tst +\ No newline at end of file ++echo $tst ++ ++if eval " ++false ++"; then ++ echo should have failed ++else ++ echo failed as expected ++fi +-- +2.33.0 + diff --git a/backport-term-ns8250-spcr-Return-if-redirection-is-disabled.patch b/backport-term-ns8250-spcr-Return-if-redirection-is-disabled.patch new file mode 100644 index 0000000..d693b65 --- /dev/null +++ b/backport-term-ns8250-spcr-Return-if-redirection-is-disabled.patch @@ -0,0 +1,38 @@ +From f0a08324d0f923527ba611887a3780c1f2cb1578 Mon Sep 17 00:00:00 2001 +From: Benjamin Herrenschmidt +Date: Tue, 21 Jan 2025 11:01:26 -0600 +Subject: [PATCH] term/ns8250-spcr: Return if redirection is disabled + +The Microsoft spec for SPCR says "The base address of the Serial Port +register set described using the ACPI Generic Address Structure, or +0 if console redirection is disabled". So, return early if redirection +is disabled (base address = 0). If this check is not done we may get +invalid ports on machines with redirection disabled and boot may hang +when reading the grub.cfg file. + +Signed-off-by: Benjamin Herrenschmidt +Reviewed-by: Leo Sandoval +Reviewed-by: Daniel Kiper +--- + grub-core/term/ns8250-spcr.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/grub-core/term/ns8250-spcr.c b/grub-core/term/ns8250-spcr.c +index 4efaaf768..428b2d59a 100644 +--- a/grub-core/term/ns8250-spcr.c ++++ b/grub-core/term/ns8250-spcr.c +@@ -76,6 +76,11 @@ grub_ns8250_spcr_init (void) + config.speed = 115200; + break; + }; ++ ++ /* If base address is 0 it means redirection is disabled. */ ++ if (spcr->base_addr.addr == 0) ++ return NULL; ++ + switch (spcr->base_addr.space_id) + { + case GRUB_ACPI_GENADDR_MEM_SPACE: +-- +2.33.0 + diff --git a/grub.patches b/grub.patches index 1c8a731..e19031f 100644 --- a/grub.patches +++ b/grub.patches @@ -325,3 +325,16 @@ Patch328: backport-fix-CVE-2024-56738.patch Patch329: LoongArch-bugfix-clear-buffer-for-screen-info.patch Patch330: 0001-i386-Check-for-cpuid-family-when-flush-cache-only-on.patch Patch331: 0002-i386-Reduce-the-time-of-set-VESA-mode-by-clearing-FB.patch +Patch332: backport-kern-i386-tsc_pmtimer-The-GRUB-menu-gets-stuck-due-t.patch +Patch333: backport-i386-tsc-The-GRUB-menu-gets-stuck-due-to-unserialize.patch +Patch334: backport-commands-file-Fix-NULL-dereference-in-the-knetbsd-te.patch +Patch335: backport-script-execute-Don-t-let-trailing-blank-lines-determ.patch +Patch336: backport-kern-partition-Unbreak-support-for-nested-partitions.patch +Patch337: backport-net-drivers-ieee1275-ofnet-Add-missing-grub_malloc.patch +Patch338: backport-fs-ntfs-Fix-NULL-pointer-dereference-and-possible-in.patch +Patch339: backport-disk-ldm-Fix-memory-leaks.patch +Patch340: backport-lib-reloacator-Fix-memory-leaks.patch +Patch341: backport-loader-i386-linux-Fix-resource-leak.patch +Patch342: backport-term-ns8250-spcr-Return-if-redirection-is-disabled.patch +Patch343: backport-fs-zfs-Fix-a-number-of-memory-leaks-in-ZFS-code.patch +Patch344: backport-fs-btrfs-Fix-memory-leaks.patch diff --git a/grub2.spec b/grub2.spec index ad851cd..b959e1d 100644 --- a/grub2.spec +++ b/grub2.spec @@ -23,7 +23,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 43 +Release: 44 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -464,6 +464,24 @@ fi %{_datadir}/man/man* %changelog +* Mon Aug 18 2025 zhangqiumiao - 1:2.12-44 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:fs/btrfs: Fix memory leaks + fs/zfs: Fix a number of memory leaks in ZFS code + term/ns8250-spcr: Return if redirection is disabled + loader/i386/linux: Fix resource leak + lib/reloacator: Fix memory leaks + disk/ldm: Fix memory leaks + fs/ntfs: Fix NULL pointer dereference and possible infinite loop + net/drivers/ieee1275/ofnet: Add missing grub_malloc() + kern/partition: Unbreak support for nested partitions + script/execute: Don't let trailing blank lines determine the return code + commands/file: Fix NULL dereference in the knetbsd tests + i386/tsc: The GRUB menu gets stuck due to unserialized rdtsc + kern/i386/tsc_pmtimer: The GRUB menu gets stuck due to failed calibration + * Wed Aug 13 2025 LeoLiu-oc - 1:2.12-43 - Type:bugfix - CVE:NA -- Gitee