Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package grub2 for openSUSE:Factory checked 
in at 2026-04-30 20:25:43
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/grub2 (Old)
 and      /work/SRC/openSUSE:Factory/.grub2.new.30200 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "grub2"

Thu Apr 30 20:25:43 2026 rev:389 rq:1349907 version:2.14

Changes:
--------
--- /work/SRC/openSUSE:Factory/grub2/grub2.changes      2026-04-22 
17:12:55.220991292 +0200
+++ /work/SRC/openSUSE:Factory/.grub2.new.30200/grub2.changes   2026-04-30 
20:25:51.931687227 +0200
@@ -1,0 +2,75 @@
+Wed Apr 29 01:10:02 UTC 2026 - Michael Chang <[email protected]>
+
+- Fix incorrect default entry and bump counter for BLS boot counter files
+  (bsc#1262580)
+  * 0001-bls-fix-default-entry-and-bumpcounter-for-BLS-boot-c.patch
+
+-------------------------------------------------------------------
+Mon Apr 20 09:03:24 UTC 2026 - Michael Chang <[email protected]>
+
+- VUL-0: grub: potentially problematic utf8 conversion in bli patches 
(bsc#1262129)
+  * 0001-Fix-problematic-utf8-conversion-in-bli-patches.patch
+
+-------------------------------------------------------------------
+Fri Apr 17 07:45:21 UTC 2026 - Radoslav Kolev <[email protected]>
+
+- Fix build for glibc 2.43 by taking upstream changes (bsc#1257256)
+  * 0001-osdep-linux-ofpath-Update-strstr-calls.patch
+  * 0001-util-probe-Save-strrchr-ret-val-to-const-data-ptr.patch
+  * 0002-util-resolve-Save-str-r-chr-ret-val-to-const-data-pt.patch
+
+-------------------------------------------------------------------
+Tue Apr 14 12:34:01 UTC 2026 - Danilo Spinella <[email protected]>
+
+- Fix string to integer conversion for LoaderConfigTimeout
+  * 0004-bli-Add-support-for-LoaderConfigTimeout-and-LoaderCo.patch
+
+-------------------------------------------------------------------
+Tue Apr 14 00:39:13 UTC 2026 - Michael Chang <[email protected]>
+
+- grub2.spec: When building the grubbls image, do not hardcode the timeout
+  value in the early config because it is set by bli.mod when it is loaded
+- grub2.spec: Remove hardcoded terminal and theme settings from the early
+  config as they are now applied at runtime
+
+-------------------------------------------------------------------
+Mon Apr 13 07:12:45 UTC 2026 - Michael Chang <[email protected]>
+
+- Fix missing install device check in grub2-install on PowerPC which could lead
+  to bootlist corruption (bsc#1221126)
+  * 0001-Mandatory-install-device-check-for-PowerPC.patch
+
+-------------------------------------------------------------------
+Tue Apr  7 06:45:13 UTC 2026 - Michael Chang <[email protected]>
+
+- Fix double free in xen booting if root filesystem is Btrfs (bsc#1259543)
+  * grub2-btrfs-01-add-ability-to-boot-from-subvolumes.patch
+  * grub2-btrfs-09-get-default-subvolume.patch
+
+-------------------------------------------------------------------
+Mon Mar 23 16:16:32 UTC 2026 - Danilo Spinella <[email protected]>
+
+- Rewrite BLI patches:
+  * 0001-blsuki-Add-support-for-LoaderEntries.patch
+  * 0002-menu-Allow-default-entry-to-have-.conf-suffix.patch
+  * 0003-bli-Add-support-for-LoaderEntryDefault-and-LoaderEnt.patch
+  * 0004-bli-Add-support-for-LoaderConfigTimeout-and-LoaderCo.patch
+  * 0005-bls_bumpcounter-Add-command-to-bump-boot-counter-for.patch
+  * 0006-bli-Add-support-for-LoaderFeatures.patch
+  * 0007-blsuki-Fix-sorting-for-entries-with-boot-counting-en.patch
+  * 0008-blsuki-append-leftover-LoaderEntries.patch
+  * 0009-blsuki-conservative-UTF-8-buffer-size.patch
+- Remove patches:
+  * 0001-bls-Accept-.conf-suffix-in-setting-default-entry.patch
+  * grub2-bls-boot-counting.patch
+  * grub2-bls-boot-assessment.patch
+  * grub2-blscfg-set-efivars.patch
+  * grub2-bls-loader-entry-oneshot.patch
+  * grub2-blsbumpcounter-menu.patch
+  * grub2-bls-loader-entry-default.patch
+  * grub2-bls-loader-entries-boot-counting.patch
+  * grub2-bls-loader-features.patch
+  * grub2-bls-loader-config-timeout.patch
+  * grub2-bls-loader-config-timeout-fix.patch
+
+-------------------------------------------------------------------

Old:
----
  0001-bls-Accept-.conf-suffix-in-setting-default-entry.patch
  grub2-bls-boot-assessment.patch
  grub2-bls-boot-counting.patch
  grub2-bls-loader-config-timeout-fix.patch
  grub2-bls-loader-config-timeout.patch
  grub2-bls-loader-entries-boot-counting.patch
  grub2-bls-loader-entry-default.patch
  grub2-bls-loader-entry-oneshot.patch
  grub2-bls-loader-features.patch
  grub2-blsbumpcounter-menu.patch
  grub2-blscfg-set-efivars.patch

New:
----
  0001-Fix-problematic-utf8-conversion-in-bli-patches.patch
  0001-Mandatory-install-device-check-for-PowerPC.patch
  0001-bls-fix-default-entry-and-bumpcounter-for-BLS-boot-c.patch
  0001-blsuki-Add-support-for-LoaderEntries.patch
  0001-osdep-linux-ofpath-Update-strstr-calls.patch
  0001-util-probe-Save-strrchr-ret-val-to-const-data-ptr.patch
  0002-menu-Allow-default-entry-to-have-.conf-suffix.patch
  0002-util-resolve-Save-str-r-chr-ret-val-to-const-data-pt.patch
  0003-bli-Add-support-for-LoaderEntryDefault-and-LoaderEnt.patch
  0004-bli-Add-support-for-LoaderConfigTimeout-and-LoaderCo.patch
  0005-bls_bumpcounter-Add-command-to-bump-boot-counter-for.patch
  0006-bli-Add-support-for-LoaderFeatures.patch
  0007-blsuki-Fix-sorting-for-entries-with-boot-counting-en.patch
  0008-blsuki-append-leftover-LoaderEntries.patch
  0009-blsuki-conservative-UTF-8-buffer-size.patch

----------(Old B)----------
  Old:- Remove patches:
  * 0001-bls-Accept-.conf-suffix-in-setting-default-entry.patch
  * grub2-bls-boot-counting.patch
  Old:  * grub2-bls-boot-counting.patch
  * grub2-bls-boot-assessment.patch
  * grub2-blscfg-set-efivars.patch
  Old:  * 0001-bls-Accept-.conf-suffix-in-setting-default-entry.patch
  * grub2-bls-boot-counting.patch
  * grub2-bls-boot-assessment.patch
  Old:  * grub2-bls-loader-config-timeout.patch
  * grub2-bls-loader-config-timeout-fix.patch
  Old:  * grub2-bls-loader-features.patch
  * grub2-bls-loader-config-timeout.patch
  * grub2-bls-loader-config-timeout-fix.patch
  Old:  * grub2-bls-loader-entry-default.patch
  * grub2-bls-loader-entries-boot-counting.patch
  * grub2-bls-loader-features.patch
  Old:  * grub2-blsbumpcounter-menu.patch
  * grub2-bls-loader-entry-default.patch
  * grub2-bls-loader-entries-boot-counting.patch
  Old:  * grub2-blscfg-set-efivars.patch
  * grub2-bls-loader-entry-oneshot.patch
  * grub2-blsbumpcounter-menu.patch
  Old:  * grub2-bls-loader-entries-boot-counting.patch
  * grub2-bls-loader-features.patch
  * grub2-bls-loader-config-timeout.patch
  Old:  * grub2-bls-loader-entry-oneshot.patch
  * grub2-blsbumpcounter-menu.patch
  * grub2-bls-loader-entry-default.patch
  Old:  * grub2-bls-boot-assessment.patch
  * grub2-blscfg-set-efivars.patch
  * grub2-bls-loader-entry-oneshot.patch
----------(Old E)----------

----------(New B)----------
  New:- VUL-0: grub: potentially problematic utf8 conversion in bli patches 
(bsc#1262129)
  * 0001-Fix-problematic-utf8-conversion-in-bli-patches.patch
  New:  to bootlist corruption (bsc#1221126)
  * 0001-Mandatory-install-device-check-for-PowerPC.patch
  New:  (bsc#1262580)
  * 0001-bls-fix-default-entry-and-bumpcounter-for-BLS-boot-c.patch
  New:- Rewrite BLI patches:
  * 0001-blsuki-Add-support-for-LoaderEntries.patch
  * 0002-menu-Allow-default-entry-to-have-.conf-suffix.patch
  New:- Fix build for glibc 2.43 by taking upstream changes (bsc#1257256)
  * 0001-osdep-linux-ofpath-Update-strstr-calls.patch
  * 0001-util-probe-Save-strrchr-ret-val-to-const-data-ptr.patch
  New:  * 0001-osdep-linux-ofpath-Update-strstr-calls.patch
  * 0001-util-probe-Save-strrchr-ret-val-to-const-data-ptr.patch
  * 0002-util-resolve-Save-str-r-chr-ret-val-to-const-data-pt.patch
  New:  * 0001-blsuki-Add-support-for-LoaderEntries.patch
  * 0002-menu-Allow-default-entry-to-have-.conf-suffix.patch
  * 0003-bli-Add-support-for-LoaderEntryDefault-and-LoaderEnt.patch
  New:  * 0001-util-probe-Save-strrchr-ret-val-to-const-data-ptr.patch
  * 0002-util-resolve-Save-str-r-chr-ret-val-to-const-data-pt.patch
  New:  * 0002-menu-Allow-default-entry-to-have-.conf-suffix.patch
  * 0003-bli-Add-support-for-LoaderEntryDefault-and-LoaderEnt.patch
  * 0004-bli-Add-support-for-LoaderConfigTimeout-and-LoaderCo.patch
  New:- Fix string to integer conversion for LoaderConfigTimeout
  * 0004-bli-Add-support-for-LoaderConfigTimeout-and-LoaderCo.patch
  New:  * 0004-bli-Add-support-for-LoaderConfigTimeout-and-LoaderCo.patch
  * 0005-bls_bumpcounter-Add-command-to-bump-boot-counter-for.patch
  * 0006-bli-Add-support-for-LoaderFeatures.patch
  New:  * 0005-bls_bumpcounter-Add-command-to-bump-boot-counter-for.patch
  * 0006-bli-Add-support-for-LoaderFeatures.patch
  * 0007-blsuki-Fix-sorting-for-entries-with-boot-counting-en.patch
  New:  * 0006-bli-Add-support-for-LoaderFeatures.patch
  * 0007-blsuki-Fix-sorting-for-entries-with-boot-counting-en.patch
  * 0008-blsuki-append-leftover-LoaderEntries.patch
  New:  * 0007-blsuki-Fix-sorting-for-entries-with-boot-counting-en.patch
  * 0008-blsuki-append-leftover-LoaderEntries.patch
  * 0009-blsuki-conservative-UTF-8-buffer-size.patch
  New:  * 0008-blsuki-append-leftover-LoaderEntries.patch
  * 0009-blsuki-conservative-UTF-8-buffer-size.patch
- Remove patches:
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ grub2.spec ++++++
--- /var/tmp/diff_new_pack.hIjhwA/_old  2026-04-30 20:25:56.163860923 +0200
+++ /var/tmp/diff_new_pack.hIjhwA/_new  2026-04-30 20:25:56.163860923 +0200
@@ -359,7 +359,6 @@
 Patch232:       0001-ieee1275-support-added-for-multiple-nvme-bootpaths.patch
 Patch236:       0001-kern-main-Fix-cmdpath-in-root-directory.patch
 Patch237:       grub2-s390x-secure-execution-support.patch
-Patch259:       0001-bls-Accept-.conf-suffix-in-setting-default-entry.patch
 Patch263:       0001-autofs-Ignore-zfs-not-found.patch
 Patch264:       0001-s390x-emu-Pass-through-PAES-cipher-as-AES.patch
 Patch274:       0001-ofpath-Add-error-check-in-NVMEoF-device-translation.patch
@@ -367,15 +366,10 @@
 Patch277:       0001-prep_loadenv-Measure-the-environment-block-into-PCR-.patch
 Patch294:       0001-Fix-PowerPC-CAS-reboot-to-evaluate-menu-context.patch
 Patch295:       0001-blscfg-read-fragments-in-order.patch
-Patch296:       grub2-bls-boot-counting.patch
-Patch297:       grub2-bls-boot-assessment.patch
 Patch298:       grub2-bls-boot-show-snapshot.patch
-Patch300:       grub2-blscfg-set-efivars.patch
 Patch309:       0001-Improve-TPM-key-protection-on-boot-interruptions.patch
 Patch310:       0004-Key-revocation-on-out-of-bound-file-access.patch
-Patch311:       grub2-bls-loader-entry-oneshot.patch
 Patch312:       0001-mkconfig-Determine-GRUB_DISTRIBUTOR-from-etc-SUSE-br.patch
-Patch313:       grub2-blsbumpcounter-menu.patch
 Patch315:       0001-test-Fix-f-test-on-files-over-network.patch
 Patch316:       0002-http-Return-HTTP-status-code-in-http_establish.patch
 Patch317:       0003-docs-Clarify-test-for-files-on-TFTP-and-HTTP.patch
@@ -385,11 +379,7 @@
 Patch336:       0002-linux-fallback-to-direct-PE-entry-boot-on-arm64.patch
 Patch337:       0003-efi-chainloader-fallback-to-direct-image-execution.patch
 Patch338:       0004-efi-chainloader-fix-missing-file_path-in-loaded_imag.patch
-Patch342:       grub2-bls-loader-entry-default.patch
 Patch344:       grub2-i386-pc-no-pageflipping.patch
-Patch401:       grub2-bls-loader-entries-boot-counting.patch
-Patch402:       grub2-bls-loader-features.patch
-Patch403:       grub2-bls-loader-config-timeout.patch
 Patch404:       0001-editenv-create-health_check_flag-env-var-on-RW-raw-b.patch
 Patch405:       0001-00_header-Omit-loading-efi_uga-on-non-x86-EFI-platfo.patch
 Patch406:       0001-Revert-configure-Print-a-more-helpful-error-if-autoc.patch
@@ -398,8 +388,22 @@
 Patch409:       0001-bls-Allow-configuration-of-active-console-type.patch
 Patch410:       0002-grubbls-Add-automatic-fwsetup-menu-entry.patch
 Patch411:       0001-ieee1275-support-dm-multipath-bootlist.patch
-Patch412:       grub2-bls-loader-config-timeout-fix.patch
 Patch413:       0001-mdraid1x-fix-raid_disks-decoding-on-big-endian-syste.patch
+Patch414:       0001-blsuki-Add-support-for-LoaderEntries.patch
+Patch415:       0002-menu-Allow-default-entry-to-have-.conf-suffix.patch
+Patch416:       0003-bli-Add-support-for-LoaderEntryDefault-and-LoaderEnt.patch
+Patch417:       0004-bli-Add-support-for-LoaderConfigTimeout-and-LoaderCo.patch
+Patch418:       0005-bls_bumpcounter-Add-command-to-bump-boot-counter-for.patch
+Patch419:       0006-bli-Add-support-for-LoaderFeatures.patch
+Patch420:       0007-blsuki-Fix-sorting-for-entries-with-boot-counting-en.patch
+Patch421:       0008-blsuki-append-leftover-LoaderEntries.patch
+Patch422:       0009-blsuki-conservative-UTF-8-buffer-size.patch
+Patch423:       0001-Mandatory-install-device-check-for-PowerPC.patch
+Patch424:       0001-osdep-linux-ofpath-Update-strstr-calls.patch
+Patch425:       0001-util-probe-Save-strrchr-ret-val-to-const-data-ptr.patch
+Patch426:       0002-util-resolve-Save-str-r-chr-ret-val-to-const-data-pt.patch
+Patch427:       0001-Fix-problematic-utf8-conversion-in-bli-patches.patch
+Patch428:       0001-bls-fix-default-entry-and-bumpcounter-for-BLS-boot-c.patch
 
 %if 0%{?suse_version} < 1600
 Requires:       gettext-runtime
@@ -733,7 +737,7 @@
 %define _configure ../configure
 
 # We don't want to let rpm override *FLAGS with default a.k.a bogus values.
-CFLAGS="-fno-strict-aliasing -fno-inline-functions-called-once 
-Wno-error=discarded-qualifiers"
+CFLAGS="-fno-strict-aliasing -fno-inline-functions-called-once"
 CXXFLAGS=" "
 FFLAGS=" "
 export CFLAGS CXXFLAGS FFLAGS
@@ -784,7 +788,7 @@
 PXE_MODULES="tftp http"
 CRYPTO_MODULES="luks luks2 gcry_rijndael gcry_sha1 gcry_sha256 gcry_sha512 
crypttab"
 %ifarch %{efi}
-CD_MODULES="${CD_MODULES} chain efifwsetup efinet read tpm tss2 
tpm2_key_protector memdisk tar squash4 xzio blsuki blsbumpcounter"
+CD_MODULES="${CD_MODULES} chain efifwsetup efinet read tpm tss2 
tpm2_key_protector memdisk tar squash4 xzio blsuki bls_bumpcounter"
 PXE_MODULES="${PXE_MODULES} efinet"
 %else
 CD_MODULES="${CD_MODULES} net ofnet"
@@ -858,23 +862,10 @@
 
 regexp --set 1:root '\((.*)\)' "$cmdpath"
 
-set timeout=8
 set gfxmode=auto
 set gfxpayload=keep
 set enable_blscfg=1
 
-terminal_input console
-terminal_output console
-terminal_output --append gfxterm
-
-loadfont (memdisk)/boot/grub/themes/DejaVuSans-Bold14.pf2
-loadfont (memdisk)/boot/grub/themes/DejaVuSans10.pf2
-loadfont (memdisk)/boot/grub/themes/DejaVuSans12.pf2
-loadfont (memdisk)/boot/grub/themes/ascii.pf2
-
-set theme=(memdisk)/boot/grub/themes/theme.txt
-export theme
-
 EOF
 
 %if 0%{?suse_version} > 1500
@@ -890,7 +881,7 @@
     %{?sbat_generation:--sbat sbat.csv} \
     -d grub-core \
     all_video boot font gfxmenu gfxterm gzio halt jpeg minicmd normal part_gpt 
png reboot video \
-    fat tpm tss2 tpm2_key_protector memdisk tar squash4 xzio blsuki 
blsbumpcounter linux bli regexp loadenv test echo true sleep efifwsetup
+    fat tpm tss2 tpm2_key_protector memdisk tar squash4 xzio blsuki 
bls_bumpcounter linux bli regexp loadenv test echo true sleep efifwsetup
 %endif
 
 %ifarch x86_64 aarch64

++++++ 0001-Fix-problematic-utf8-conversion-in-bli-patches.patch ++++++
>From 38b8a8feec4c48d7d4aa6731955b2a96c0d2ec7d Mon Sep 17 00:00:00 2001
From: Michael Chang <[email protected]>
Date: Thu, 16 Apr 2026 11:11:10 +0800
Subject: [PATCH] Fix problematic utf8 conversion in bli patches

Use UTF-16 code unit counts in grub-core/commands/bli.c when converting
EFI variable data to UTF-8. Allocate the UTF-8 buffer with checked size
growth, convert using the correct UTF-16 element count, and always
append a terminating NUL. This avoids heap overreads, heap overflows,
and unterminated strings when EFI variable contents are malformed or
larger than expected.

Fix filename growth handling in grub-core/commands/bls_bumpcounter.c by
accounting for the extra UTF-16 storage needed when appending "-1" to
the filename. Use checked size expansion before reallocating the EFI
file info buffer, and pass the UTF-16 destination length in code units
to grub_utf8_to_utf16(). This prevents writing past FileName when the
renamed entry becomes longer.

Bound the scan of LoaderEntries in grub-core/commands/blsuki.c by the
EFI variable size instead of assuming that the data is always
NUL-terminated. If no UTF-16 terminator is found within the reported
variable size, treat the variable as malformed and fail cleanly. This
avoids out-of-bounds reads on corrupted or malicious EFI variable
contents.

Signed-off-by: Michael Chang <[email protected]>
---
 grub-core/commands/bli.c             | 26 +++++++++++++++++++++-----
 grub-core/commands/bls_bumpcounter.c | 13 +++++++++----
 grub-core/commands/blsuki.c          | 24 +++++++++++++++++++++---
 3 files changed, 51 insertions(+), 12 deletions(-)

diff --git a/grub-core/commands/bli.c b/grub-core/commands/bli.c
index 72a3a4edc..c90c9b404 100644
--- a/grub-core/commands/bli.c
+++ b/grub-core/commands/bli.c
@@ -177,19 +177,35 @@ static char*
 get_efivar (const char* efivar)
 {
   grub_efi_status_t status;
-  grub_size_t size;
+  grub_size_t size, size16;
   grub_efi_char16_t *val_efi = NULL;
   char *val = NULL;
+
   status = grub_efi_get_variable (efivar,
                                  &bli_vendor_guid,
                                  &size,
                                  (void**) &val_efi);
-  if (status == GRUB_EFI_SUCCESS && size != 0)
+
+  size16 = size / sizeof (*val_efi);
+  if (status == GRUB_EFI_SUCCESS && size16 > 0)
     {
-      val = grub_malloc (size * sizeof (char));
-      grub_utf16_to_utf8 ((grub_uint8_t*) val,
-                         (grub_uint16_t*) val_efi, size);
+      grub_size_t size_utf8;
+
+      if (grub_mul (size16, GRUB_MAX_UTF8_PER_UTF16, &size_utf8) ||
+         grub_add (size_utf8, 1, &size_utf8))
+       {
+         grub_error (GRUB_ERR_OUT_OF_RANGE, "size overflow when converting EFI 
variable %s to UTF-8", efivar);
+         goto finish;
+       }
+      val = grub_malloc (size_utf8);
+      if (val == NULL)
+       goto finish;
+      *grub_utf16_to_utf8 ((grub_uint8_t*) val,
+                         (grub_uint16_t*) val_efi, size16) = '\0';
     }
+
+finish:
+  grub_free (val_efi);
   return val;
 }
 
diff --git a/grub-core/commands/bls_bumpcounter.c 
b/grub-core/commands/bls_bumpcounter.c
index 014389567..d45fe276c 100644
--- a/grub-core/commands/bls_bumpcounter.c
+++ b/grub-core/commands/bls_bumpcounter.c
@@ -192,9 +192,13 @@ grub_cmd_bls_bumpcounter (grub_extcmd_context_t ctxt 
__attribute__ ((unused)),
     {
       grub_free(file_info);
       /* When we bump the counter, it might happen that we increase the 
filename
-         length. Add the space for 2 more characters. (i.e. adding the boot 
done
-         part "-1") */
-      size += 2;
+         length. Add the space for 2 more characters (4 bytes). (i.e. adding 
the
+         boot done part "-1") */
+      if (grub_add (size, 4, &size))
+       {
+         grub_error (GRUB_ERR_OUT_OF_RANGE, N_("size overflow"));
+         goto finish;
+       }
       file_info = grub_malloc (size);
       if (!file_info)
        {
@@ -218,7 +222,8 @@ grub_cmd_bls_bumpcounter (grub_extcmd_context_t ctxt 
__attribute__ ((unused)),
 
   grub_dprintf ("bls_bumpcounter", "renaming entry to %s\n", new_path);
   grub_utf8_to_utf16 (file_info->FileName,
-                     size - offsetof (grub_efi_file_info_t, FileName),
+                     (size - offsetof (grub_efi_file_info_t, FileName))
+              / sizeof (grub_efi_char16_t),
                      (grub_uint8_t*) new_path, grub_strlen (new_path), NULL);
 
   err = handle->SetInfo (handle, &grub_efi_file_info_guid, size, file_info);
diff --git a/grub-core/commands/blsuki.c b/grub-core/commands/blsuki.c
index e692bbe69..4dfc4934e 100644
--- a/grub-core/commands/blsuki.c
+++ b/grub-core/commands/blsuki.c
@@ -1539,7 +1539,7 @@ set_bli_loader_entries (enum blsuki_cmd_type cmd_type)
   grub_size_t size = 0, remaining_size, len, written, prev_entries_size = 0, 
len16;
   grub_efi_char16_t *prev_entries_start = NULL;
   grub_size_t prev_entries_start_size = 0;
-  grub_efi_char16_t *efi_entries = NULL, *prev_entries = NULL, *p = NULL, 
*tmp16;
+  grub_efi_char16_t *efi_entries = NULL, *prev_entries = NULL, *p = NULL;
   char *boot_counting_idx, *prev_entry;
   const char* env = NULL;
   grub_efi_status_t status;
@@ -1624,12 +1624,30 @@ set_bli_loader_entries (enum blsuki_cmd_type cmd_type)
            {
              do {
                grub_size_t prev_entry_size;
+               grub_size_t prev_entries_size16 = prev_entries_size / sizeof 
(*prev_entries);
 
-               tmp16 = prev_entries;
                len16 = 0;
-               while (*tmp16++ != '\0')
+               /*
+                * LoaderEntries comes from EFI variable storage, so it is only
+                * trusted up to prev_entries_size16 UTF-16 code units. Bound
+                * the scan in case a malformed variable is missing a
+                * terminator.
+                */
+               while (len16 < prev_entries_size16 && prev_entries[len16] != 
'\0')
                    len16++;
 
+               /*
+                * If we reached the end of the buffer without finding a null
+                * terminator, the variable is malformed and we should bail
+                * instead of risking an out-of-bounds read.
+                */
+               if (len16 == prev_entries_size16)
+                 {
+                   grub_free (prev_entries_start);
+                   grub_free (efi_entries);
+                   return grub_error (GRUB_ERR_BAD_ARGUMENT, "malformed 
LoaderEntries variable");
+                 }
+
                if (grub_mul (len16, GRUB_MAX_UTF8_PER_UTF16, &prev_entry_size) 
||
                    grub_add (prev_entry_size, 1, &prev_entry_size))
                  {
-- 
2.53.0


++++++ 0001-Mandatory-install-device-check-for-PowerPC.patch ++++++
>From 34de9a5984c9a9e84717dd6ed7a6ba255f09bb0a Mon Sep 17 00:00:00 2001
From: Avnish Chouhan <[email protected]>
Date: Tue, 27 Jan 2026 19:18:14 +0530
Subject: [PATCH] Mandatory install device check for PowerPC

This patch adds a check on install_device while installing grub for PowerPC.
If install_device is not mentioned in grub2-install and machine is detected
as PowerPC, the error will be thrown and it will terminates the grub2-install
operation. Running grub2-install on PowerPC without the install_device may
result in bootlist corruption. When no install device is specified, it attempts
to load images from the filesystem, which leads to nvram bootlist corruption.
The idea is to fail the operation and avoid creating the invalid boot entry.

Signed-off-by: Avnish Chouhan <[email protected]>
Link: https://patch.msgid.link/[email protected]
---
 util/grub-install.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/util/grub-install.c b/util/grub-install.c
index 926f49457..226146899 100644
--- a/util/grub-install.c
+++ b/util/grub-install.c
@@ -1435,6 +1435,19 @@ main (int argc, char *argv[])
              is_prep = 0;
            }
        }
+#if defined(__powerpc__)
+     else
+       {
+         /*
+          * As the machine has been detected as PowerPC and not a PowerMac. We 
need to check
+          * whether the install_device has been mentioned while installing. If 
no device has been
+          * mentioned, we need to exit and mark it as an error as the 
install_device is required for
+          * PowerPC installation. An installation with no device mentioned may 
lead to corruptions.
+          */
+          if (!install_device)
+            grub_util_error ("%s", _("install device isn't specified, required 
for PowerPC"));
+       }
+#endif /* __powerpc__ */
     }
 
   if (platform == GRUB_INSTALL_PLATFORM_S390X_EMU)
-- 
2.53.0


++++++ 0001-bls-fix-default-entry-and-bumpcounter-for-BLS-boot-c.patch ++++++
>From fb62215386831db2a85b9b73cfb77f1567a24f78 Mon Sep 17 00:00:00 2001
From: Michael Chang <[email protected]>
Date: Tue, 28 Apr 2026 13:02:13 +0800
Subject: [PATCH] bls: fix default entry and bumpcounter for BLS boot counter
 files

When BLS boot counting is enabled, entry filenames include counter
suffixes such as "+TRIES-DONE". This patch tries to ensure that the
default entry selection and bumpcounter operations work correctly with
these modified filenames.

Signed-off-by: Michael Chang <[email protected]>
---
 grub-core/commands/bls_bumpcounter.c | 32 +++++++++++++------
 grub-core/commands/blsuki.c          | 48 ++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+), 9 deletions(-)

diff --git a/grub-core/commands/bls_bumpcounter.c 
b/grub-core/commands/bls_bumpcounter.c
index d45fe276c..fe4a9ea92 100644
--- a/grub-core/commands/bls_bumpcounter.c
+++ b/grub-core/commands/bls_bumpcounter.c
@@ -102,8 +102,9 @@ grub_cmd_bls_bumpcounter (grub_extcmd_context_t ctxt 
__attribute__ ((unused)),
   grub_efi_status_t err;
   char *entry, *new_path = NULL, *old_path;
   const char *blsdir;
-  grub_efi_uint64_t size;
+  grub_efi_uint64_t size, size_info;
   grub_efi_char16_t *old_path16;
+  grub_efi_uint64_t len16;
 
   if (argc != 1) {
     grub_dprintf ("bls_bumpcounter", "only one argument should be passed\n");
@@ -160,7 +161,7 @@ grub_cmd_bls_bumpcounter (grub_extcmd_context_t ctxt 
__attribute__ ((unused)),
         blsdir = GRUB_BLS_CONFIG_PATH;
     }
 
-  old_path = grub_xasprintf ("%s%s", blsdir, entry);
+  old_path = grub_xasprintf ("%s%s.conf", blsdir, entry);
   grub_utf8_to_utf16_alloc (old_path, &old_path16, NULL);
 
   err = root->Open (root, &handle, old_path16,
@@ -179,14 +180,15 @@ grub_cmd_bls_bumpcounter (grub_extcmd_context_t ctxt 
__attribute__ ((unused)),
      most cases, and, if it fails, allocate a new one with the exact size
      returned from GetInfo.
      Reference: systemd:src/boot/efi/util.c =*/
-  size = offsetof (grub_efi_file_info_t, FileName)
+  size_info = offsetof (grub_efi_file_info_t, FileName)
                   + 256U * sizeof (grub_efi_char16_t);
-  file_info = grub_malloc (size);
+  file_info = grub_malloc (size_info);
   if (!file_info)
     {
       grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
       goto finish;
     }
+  size = size_info - 4; /* reserve space for 2 more characters (4 bytes) for 
the boot done part "-1" */
   err = handle->GetInfo (handle, &grub_efi_file_info_guid, &size, file_info);
   if (err == GRUB_EFI_BUFFER_TOO_SMALL)
     {
@@ -194,12 +196,12 @@ grub_cmd_bls_bumpcounter (grub_extcmd_context_t ctxt 
__attribute__ ((unused)),
       /* When we bump the counter, it might happen that we increase the 
filename
          length. Add the space for 2 more characters (4 bytes). (i.e. adding 
the
          boot done part "-1") */
-      if (grub_add (size, 4, &size))
+      if (grub_add (size, 4, &size_info))
        {
          grub_error (GRUB_ERR_OUT_OF_RANGE, N_("size overflow"));
          goto finish;
        }
-      file_info = grub_malloc (size);
+      file_info = grub_malloc (size_info);
       if (!file_info)
        {
          grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
@@ -221,12 +223,24 @@ grub_cmd_bls_bumpcounter (grub_extcmd_context_t ctxt 
__attribute__ ((unused)),
     goto finish;
 
   grub_dprintf ("bls_bumpcounter", "renaming entry to %s\n", new_path);
-  grub_utf8_to_utf16 (file_info->FileName,
-                     (size - offsetof (grub_efi_file_info_t, FileName))
+  len16 = grub_utf8_to_utf16 (file_info->FileName,
+                     (size_info - offsetof (grub_efi_file_info_t, FileName))
               / sizeof (grub_efi_char16_t),
                      (grub_uint8_t*) new_path, grub_strlen (new_path), NULL);
 
-  err = handle->SetInfo (handle, &grub_efi_file_info_guid, size, file_info);
+  /*
+   * Check if the new filename fits in the allocated file_info buffer. If not,
+   * it means that the entry is too long to be renamed with the bumped counter,
+   * and we should bail instead of risking an out-of-bounds write.
+   */
+  if (len16 >= (size_info - offsetof (grub_efi_file_info_t, FileName)) /
+                  sizeof (grub_efi_char16_t))
+    {
+      grub_dprintf ("bls_bumpcounter", "new filename is too long\n");
+      goto finish;
+    }
+  file_info->FileName[len16++] = '\0';
+  err = handle->SetInfo (handle, &grub_efi_file_info_guid, size_info, 
file_info);
 
   if (err != GRUB_EFI_SUCCESS)
     {
diff --git a/grub-core/commands/blsuki.c b/grub-core/commands/blsuki.c
index 4dfc4934e..8b152b443 100644
--- a/grub-core/commands/blsuki.c
+++ b/grub-core/commands/blsuki.c
@@ -1091,6 +1091,7 @@ bls_create_entry (grub_blsuki_entry_t *entry)
   char *initrd_cmd = NULL;
   char *dt_cmd = NULL;
   char *id = entry->filename;
+  char *id_dup = NULL;
   grub_size_t id_len;
   char *hotkey = NULL;
   char *users = NULL;
@@ -1111,6 +1112,52 @@ bls_create_entry (grub_blsuki_entry_t *entry)
   id_len = grub_strlen (id);
   if (id_len >= BLS_EXT_LEN && grub_strcmp (id + id_len - BLS_EXT_LEN, 
".conf") == 0)
     id[id_len - BLS_EXT_LEN] = '\0';
+  id_len = grub_strlen (id);
+  /*
+   * The menuentry ID should have the boot assessemnt counters removed, to
+   * canonicalize that default entry can be correctly matched.
+   */
+  char *tries = grub_strrchr (id, '+');
+  if (tries != NULL)
+    {
+      char *n;
+      const char *n_end = NULL;
+      char *done = grub_strrchr (tries, '-');
+      if (done != NULL)
+       n = grub_strndup (tries + 1, done - tries - 1);
+      else
+       n = grub_strdup (tries + 1);
+      if (n == NULL)
+       goto finish;
+      grub_error_push ();
+      grub_strtol (n, &n_end, 10);
+      switch (grub_errno)
+       {
+       case GRUB_ERR_NONE:
+         grub_error_pop ();
+         if (n_end && n_end != n && *n_end == '\0')
+           {
+             id_dup = grub_strdup (id);
+             if (id_dup == NULL)
+               {
+                 grub_free (n);
+                 goto finish;
+               }
+             grub_strrchr (id_dup, '+')[0] = '\0';
+           }
+         break;
+       default:
+         grub_error_pop ();
+         break;
+       }
+      grub_free (n);
+    }
+
+  if (id_dup != NULL)
+    {
+      id = id_dup;
+      id_len = grub_strlen (id);
+    }
 
   title = blsuki_get_val (entry, "title", NULL);
   if (title != NULL)
@@ -1178,6 +1225,7 @@ bls_create_entry (grub_blsuki_entry_t *entry)
   grub_free (args);
   grub_free (argv);
   grub_free (src);
+  grub_free (id_dup);
 }
 
 #ifdef GRUB_MACHINE_EFI
-- 
2.53.0


++++++ 0001-blsuki-Add-support-for-LoaderEntries.patch ++++++
>From c114cc791483dee8f833e9ed303b78b60922551b Mon Sep 17 00:00:00 2001
From: Danilo Spinella <[email protected]>
Date: Tue, 10 Mar 2026 16:38:34 +0100
Subject: [PATCH 1/9] blsuki: Add support for LoaderEntries

---
 grub-core/commands/blsuki.c | 156 ++++++++++++++++++++++++++++++++++++
 1 file changed, 156 insertions(+)

diff --git a/grub-core/commands/blsuki.c b/grub-core/commands/blsuki.c
index 4133d3111..2664a9fc4 100644
--- a/grub-core/commands/blsuki.c
+++ b/grub-core/commands/blsuki.c
@@ -33,9 +33,15 @@
 #include <filevercmp.h>
 
 #ifdef GRUB_MACHINE_EFI
+#include <grub/charset.h>
 #include <grub/efi/efi.h>
 #include <grub/efi/disk.h>
 #include <grub/efi/pe32.h>
+
+static const grub_guid_t bli_vendor_guid = 
GRUB_EFI_VENDOR_BOOT_LOADER_INTERFACE_GUID;
+
+#define GRUB_BLSUKI_ENTRIES_BLS "blsuki_entries_bls"
+#define GRUB_BLSUKI_ENTRIES_UKI "blsuki_entries_uki"
 #endif
 
 #ifdef GRUB_MACHINE_EMU
@@ -1373,6 +1379,152 @@ blsuki_is_default_entry (const char *def_entry, 
grub_blsuki_entry_t *entry, int
   return false;
 }
 
+#ifdef GRUB_MACHINE_EFI
+/* Set LoaderEntries for uki and blscfg generated entries */
+static grub_err_t
+set_bli_loader_entries (enum blsuki_cmd_type cmd_type)
+{
+  grub_blsuki_entry_t *entry = NULL;
+  grub_size_t size = 0, remaining_size, len, written, prev_entries_size = 0, 
len16;
+  grub_efi_char16_t *prev_entries_start = NULL;
+  grub_size_t prev_entries_start_size = 0;
+  grub_efi_char16_t *efi_entries = NULL, *prev_entries = NULL, *p = NULL, 
*tmp16;
+  char *boot_counting_idx, *prev_entry;
+  const char* env = NULL;
+  grub_efi_status_t status;
+  int rc;
+
+  FOR_BLSUKI_ENTRIES (entry)
+    {
+      if (entry->visible)
+       {
+         /* Calculate the size of LoaderEntries string */
+         len = grub_strlen (entry->filename);
+         /* Skip boot counting if found */
+         boot_counting_idx = grub_strrchr(entry->filename, '+');
+         if (boot_counting_idx != NULL)
+           len = boot_counting_idx - entry->filename;
+         /* Skip ".conf" extension if found */
+         else if (len > BLS_EXT_LEN
+             && grub_strcmp (entry->filename + len - BLS_EXT_LEN, ".conf") == 
0)
+           len -= BLS_EXT_LEN;
+         else if (len > UKI_EXT_LEN
+             && grub_strcmp (entry->filename + len - UKI_EXT_LEN, ".efi") == 0)
+           len -= UKI_EXT_LEN;
+
+         size += len + 1;
+       }
+    }
+
+  /* When calling blscfg command, there might be entries generated by uki 
command,
+     and viceversa. Use GRUB_BLSUKI_ENTRIES_BLS and GRUB_BLSUKI_ENTRIES_UKI 
env variables
+     to check if the current value of LoaderEntries should be appended to the 
new one */
+  if (cmd_type == BLSUKI_BLS_CMD)
+    {
+      env = grub_env_get (GRUB_BLSUKI_ENTRIES_UKI);
+    } else if (cmd_type == BLSUKI_UKI_CMD) {
+      env = grub_env_get (GRUB_BLSUKI_ENTRIES_BLS);
+    }
+  if (env && grub_strcmp (env, "1") == 0)
+    {
+      status = grub_efi_get_variable ("LoaderEntries",
+                                     &bli_vendor_guid,
+                                     &prev_entries_start_size,
+                                     (void**) &prev_entries_start);
+      /* Get the value of the other generated entries */
+      if (status != GRUB_EFI_SUCCESS || prev_entries_start_size == 0)
+       {
+         prev_entries_start = NULL;
+         prev_entries_start_size = 0;
+       }
+    }
+  efi_entries = grub_malloc (size * sizeof (grub_efi_char16_t) + 
prev_entries_start_size);
+  if (efi_entries == NULL)
+    return grub_errno;
+
+  prev_entries = prev_entries_start;
+  prev_entries_size = prev_entries_start_size;
+  p = efi_entries;
+  remaining_size = size;
+  /* Create a null separated list of all entries (with the extension removed) 
*/
+  FOR_BLSUKI_ENTRIES (entry)
+    {
+      if (entry->visible)
+       {
+         len = grub_strlen (entry->filename);
+
+         boot_counting_idx = grub_strrchr(entry->filename, '+');
+         if (boot_counting_idx != NULL)
+           len = boot_counting_idx - entry->filename;
+         else if ((len > BLS_EXT_LEN)
+             && grub_strcmp (entry->filename + len - BLS_EXT_LEN, ".conf") == 
0)
+           len -= BLS_EXT_LEN;
+         else if ((len > UKI_EXT_LEN)
+             && grub_strcmp (entry->filename + len - UKI_EXT_LEN, ".efi") == 0)
+           len -= UKI_EXT_LEN;
+
+         if (remaining_size < len + 1)
+           {
+             grub_dprintf ("blsuki", "LoaderEntries buffer too small\n");
+             break;
+           }
+
+         if (prev_entries_size != 0 && prev_entries)
+           {
+             do {
+               tmp16 = prev_entries;
+               len16 = 0;
+               while (*tmp16++ != '\0')
+                   len16++;
+               prev_entry = grub_malloc (len16 + 1);
+               *grub_utf16_to_utf8 ((grub_uint8_t*) prev_entry, prev_entries, 
len16) = '\0';
+               rc = filevercmp (prev_entry, entry->filename);
+               if (rc == 0)
+                 {
+                   grub_free (prev_entry);
+                   grub_free (prev_entries_start);
+                   grub_free (efi_entries);
+                   return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("duplicate 
file: `%s'"), entry->filename);
+                 }
+
+               if (rc > 0)
+                 {
+                   grub_memcpy (p, prev_entries, len16 * sizeof 
(*prev_entries));
+                   p += len16;
+                   *p++ = (grub_efi_char16_t) '\0';
+                   remaining_size -= len16 + 1;
+                   prev_entries += len16 + 1;
+                   prev_entries_size -= (len16 + 1) * sizeof (*prev_entries);
+                 }
+               grub_free (prev_entry);
+             } while (prev_entries_size > 0 && rc > 0);
+           }
+
+         written = grub_utf8_to_utf16 (p, remaining_size,
+                                       (grub_uint8_t*) entry->filename, len, 
NULL);
+         p += written;
+         *p++ = (grub_efi_char16_t) '\0';
+         remaining_size -= written + 1;
+       }
+    }
+
+  status = grub_efi_set_variable_with_attributes ("LoaderEntries", 
&bli_vendor_guid,
+                                        efi_entries,
+                                        size * sizeof (grub_efi_char16_t) + 
prev_entries_start_size - prev_entries_size,
+                                        GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                                        GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
+  /* Record that we set the generated entries by this command to LoaderEntries 
*/
+  if (cmd_type == BLSUKI_BLS_CMD)
+    grub_env_set (GRUB_BLSUKI_ENTRIES_BLS, "1");
+  else if (cmd_type == BLSUKI_UKI_CMD)
+    grub_env_set (GRUB_BLSUKI_ENTRIES_UKI, "1");
+  grub_free (efi_entries);
+  grub_free (prev_entries_start);
+
+  return status;
+}
+#endif
+
 /*
  * This function creates a GRUB boot menu entry for each BLS or UKI  entry in
  * the entries list.
@@ -1409,6 +1561,10 @@ blsuki_create_entries (bool show_default, bool 
show_non_default, char *entry_id,
       idx++;
     }
 
+#ifdef GRUB_MACHINE_EFI
+  set_bli_loader_entries (cmd_type);
+#endif
+
   return GRUB_ERR_NONE;
 }
 
-- 
2.53.0


++++++ 0001-osdep-linux-ofpath-Update-strstr-calls.patch ++++++
>From 675d8581037dc8996cf6db21a61d26e28f7d44c1 Mon Sep 17 00:00:00 2001
From: Nicholas Vinson <[email protected]>
Date: Tue, 24 Feb 2026 19:48:39 -0500
Subject: [PATCH] osdep/linux/ofpath: Update strstr() calls

With C23, strstr() returns a "const char *" if its first argument is
"const char *", and these changes are implemented in glibc-2.43.

As a result, the first strstr() call in check_sas() now returns a "const
char *" instead of "char *" because sysfs_path is a "const char *". This
triggers a "discards qualifiers" warning, that is later promoted to an
error and ultimately causes the build to fail.

To fix the issue, this patch converts "ed", the pointer that stores
strstr()'s return value, to a "const char *". Removes the xstrdup()
call and cleans up the rest of the function by updating the *printf()
calls and using pointer arithmetic to compute lengths instead of strlen().

Signed-off-by: Nicholas Vinson <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
---
 grub-core/osdep/linux/ofpath.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
index 24a4d5c8d..0ebfea44c 100644
--- a/grub-core/osdep/linux/ofpath.c
+++ b/grub-core/osdep/linux/ofpath.c
@@ -488,8 +488,11 @@ check_hba_identifiers (const char *sysfs_path, int 
*vendor, int *device_id)
 static void
 check_sas (const char *sysfs_path, int *tgt, unsigned long int *sas_address)
 {
-  char *ed = strstr (sysfs_path, "end_device");
-  char *p, *q, *path;
+  const char *ed = strstr (sysfs_path, "end_device");
+  int p_len;
+  int ed_len;
+  const char *q;
+  char *path;
   char phy[21];
   int fd;
   size_t path_size;
@@ -498,20 +501,16 @@ check_sas (const char *sysfs_path, int *tgt, unsigned 
long int *sas_address)
     return;
 
   /* SAS devices are identified using disk@$PHY_ID */
-  p = xstrdup (sysfs_path);
-  ed = strstr(p, "end_device");
-  if (!ed)
-    return;
-
   q = ed;
   while (*q && *q != '/')
     q++;
-  *q = '\0';
+  p_len = (int) (q - sysfs_path);
+  ed_len = (int) (q - ed);
 
-  path_size = (strlen (p) + strlen (ed)
-              + sizeof ("%s/sas_device/%s/phy_identifier"));
+  path_size = (p_len + ed_len + sizeof ("%s/sas_device/%s/phy_identifier"));
   path = xmalloc (path_size);
-  snprintf (path, path_size, "%s/sas_device/%s/phy_identifier", p, ed);
+  snprintf (path, path_size, "%.*s/sas_device/%.*s/phy_identifier", p_len,
+           sysfs_path, ed_len, ed);
   fd = open (path, O_RDONLY);
   if (fd < 0)
     grub_util_error (_("cannot open `%s': %s"), path, strerror (errno));
@@ -524,7 +523,8 @@ check_sas (const char *sysfs_path, int *tgt, unsigned long 
int *sas_address)
 
   sscanf (phy, "%d", tgt);
 
-  snprintf (path, path_size, "%s/sas_device/%s/sas_address", p, ed);
+  snprintf (path, path_size, "%.*s/sas_device/%.*s/sas_address", p_len,
+           sysfs_path, ed_len, ed);
   fd = open (path, O_RDONLY);
   if (fd < 0)
     grub_util_error (_("cannot open `%s': %s"), path, strerror (errno));
@@ -535,7 +535,6 @@ check_sas (const char *sysfs_path, int *tgt, unsigned long 
int *sas_address)
   sscanf (phy, "%lx", sas_address);
 
   free (path);
-  free (p);
   close (fd);
 }
 
-- 
2.53.0


++++++ 0001-util-probe-Save-strrchr-ret-val-to-const-data-ptr.patch ++++++
>From 9f4a586f1227a8287e1d6acd95893f6098756ee2 Mon Sep 17 00:00:00 2001
From: Nicholas Vinson <[email protected]>
Date: Tue, 24 Feb 2026 19:48:41 -0500
Subject: [PATCH 1/2] util/probe: Save strrchr() ret val to const data ptr

With glibc-2.43 implementing the C23 standard, strrchr() now returns
"const char *" when its first argument is "const char *".

The fix is update all pointers receiving strrchr()'s return value so
that they are now "const char *" instead of "char *".

Signed-off-by: Nicholas Vinson <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
---
 util/probe.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/util/probe.c b/util/probe.c
index 81d91cf59..a9158d640 100644
--- a/util/probe.c
+++ b/util/probe.c
@@ -70,7 +70,7 @@ char *
 grub_util_guess_bios_drive (const char *orig_path)
 {
   char *canon;
-  char *ptr;
+  const char *ptr;
   canon = grub_canonicalize_file_name (orig_path);
   if (!canon)
     return NULL;
@@ -99,7 +99,7 @@ char *
 grub_util_guess_efi_drive (const char *orig_path)
 {
   char *canon;
-  char *ptr;
+  const char *ptr;
   canon = grub_canonicalize_file_name (orig_path);
   if (!canon)
     return NULL;
@@ -128,7 +128,7 @@ char *
 grub_util_guess_baremetal_drive (const char *orig_path)
 {
   char *canon;
-  char *ptr;
+  const char *ptr;
   canon = grub_canonicalize_file_name (orig_path);
   if (!canon)
     return NULL;
-- 
2.53.0


++++++ 0002-menu-Allow-default-entry-to-have-.conf-suffix.patch ++++++
>From 1be3059a7867e97406edaf4c567b5ed1862ded24 Mon Sep 17 00:00:00 2001
From: Danilo Spinella <[email protected]>
Date: Wed, 11 Mar 2026 14:23:47 +0100
Subject: [PATCH 2/9] menu: Allow default entry to have ".conf" suffix

When setting default entry, accept values that ends in ".conf". Strip
the suffix when looking for the corresponding entry.
---
 grub-core/normal/menu.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

Index: grub-2.14/grub-core/normal/menu.c
===================================================================
--- grub-2.14.orig/grub-core/normal/menu.c
+++ grub-2.14/grub-core/normal/menu.c
@@ -571,7 +571,8 @@ static int
 get_entry_number (grub_menu_t menu, const char *name)
 {
   const char *val;
-  int entry;
+  char *ext;
+  int entry, res;
 
   val = grub_env_get (name);
   if (! val)
@@ -601,6 +602,23 @@ get_entry_number (grub_menu_t menu, cons
              entry = i;
              break;
            }
+
+         if (e->blsuki)
+           {
+             ext = grub_strrchr (val, '.');
+             if (ext && grub_strcmp (ext, ".conf") == 0)
+               {
+                 *ext = '\0';
+                 res = menuentry_eq (e->id, val);
+                 *ext = '.';
+                  if (res)
+                   {
+                     entry = i;
+                     break;
+                   }
+               }
+           }
+
          e = e->next;
 
          /* Skip hidden entries */

++++++ 0002-util-resolve-Save-str-r-chr-ret-val-to-const-data-pt.patch ++++++
>From ce6f2b57f5450a8239022dcbfb2d750f273b83cb Mon Sep 17 00:00:00 2001
From: Nicholas Vinson <[email protected]>
Date: Tue, 24 Feb 2026 19:48:42 -0500
Subject: [PATCH 2/2] util/resolve: Save str[r]chr() ret val to const data ptr

With glibc-2.43 implementing the C23 standard, strrchr() and strchr()
now return "const char *" when its first argument is "const char *".

The fix is update all pointers receiving strrchr() and strchr()'s return
values so that they are now "const char *" instead of "char *".

Signed-off-by: Nicholas Vinson <[email protected]>
Reviewed-by: Daniel Kiper <[email protected]>
---
 util/resolve.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/util/resolve.c b/util/resolve.c
index b6e26312f..254379195 100644
--- a/util/resolve.c
+++ b/util/resolve.c
@@ -138,12 +138,12 @@ read_dep_list (FILE *fp)
 static char *
 get_module_name (const char *str)
 {
-  char *base;
-  char *ext;
+  const char *base;
+  const char *ext;
 
   base = strrchr (str, '/');
   if (! base)
-    base = (char *) str;
+    base = str;
   else
     base++;
 
@@ -164,9 +164,9 @@ get_module_name (const char *str)
 static char *
 get_module_path (const char *prefix, const char *str)
 {
-  char *dir;
+  const char *dir;
   char *base;
-  char *ext;
+  const char *ext;
   char *ret;
 
   ext = strrchr (str, '.');
-- 
2.53.0


++++++ 0003-bli-Add-support-for-LoaderEntryDefault-and-LoaderEnt.patch ++++++
>From 688d4f6be407e5d5669469b1fa166eb50d789a42 Mon Sep 17 00:00:00 2001
From: Danilo Spinella <[email protected]>
Date: Wed, 11 Mar 2026 15:06:27 +0100
Subject: [PATCH 3/9] bli: Add support for LoaderEntryDefault and
 LoaderEntryOneShot

---
 grub-core/commands/bli.c | 44 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/grub-core/commands/bli.c b/grub-core/commands/bli.c
index 38f52f87a..0b4e1259a 100644
--- a/grub-core/commands/bli.c
+++ b/grub-core/commands/bli.c
@@ -149,6 +149,49 @@ set_loader_active_pcr_banks (void)
   return status;
 }
 
+/* Get the value of a EFI variable */
+static char*
+get_efivar (const char* efivar)
+{
+  grub_efi_status_t status;
+  grub_size_t size;
+  grub_efi_char16_t *val_efi = NULL;
+  char *val = NULL;
+  status = grub_efi_get_variable (efivar,
+                                 &bli_vendor_guid,
+                                 &size,
+                                 (void**) &val_efi);
+  if (status == GRUB_EFI_SUCCESS && size != 0)
+    {
+      val = grub_malloc (size * sizeof (char));
+      grub_utf16_to_utf8 ((grub_uint8_t*) val,
+                         (grub_uint16_t*) val_efi, size);
+    }
+  return val;
+}
+
+static void
+set_loader_default_entry (void)
+{
+  char* default_entry;
+  char* oneshot_entry = get_efivar("LoaderEntryOneShot");
+
+  if (oneshot_entry != NULL)
+    {
+      grub_env_set ("default", oneshot_entry);
+      grub_efi_set_variable_to_string("LoaderEntryOneShot",
+                                     &bli_vendor_guid, "", 0);
+    }
+  else
+    {
+      default_entry = get_efivar("LoaderEntryDefault");
+      if (default_entry != NULL)
+       {
+         grub_env_set ("default", default_entry);
+       }
+    }
+}
+
 GRUB_MOD_INIT (bli)
 {
   grub_efi_set_variable_to_string ("LoaderInfo", &bli_vendor_guid, 
PACKAGE_STRING,
@@ -156,6 +199,7 @@ GRUB_MOD_INIT (bli)
                                   GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
   set_loader_device_part_uuid ();
   set_loader_active_pcr_banks ();
+  set_loader_default_entry ();
   /* No error here is critical, other than being logged */
   grub_print_error ();
 }
-- 
2.53.0


++++++ 0004-bli-Add-support-for-LoaderConfigTimeout-and-LoaderCo.patch ++++++
>From 7f4877566b95db91c0df62fb2bccac1a244c5170 Mon Sep 17 00:00:00 2001
From: Danilo Spinella <[email protected]>
Date: Wed, 11 Mar 2026 17:55:47 +0100
Subject: [PATCH 4/9] bli: Add support for LoaderConfigTimeout and
 LoaderConfigTimeoutOneShot

Add new timeout_style "disabled" to match Boot Loader Interface.
---
 grub-core/commands/bli.c | 79 ++++++++++++++++++++++++++++++++++++++++
 grub-core/normal/menu.c  |  9 +++--
 2 files changed, 85 insertions(+), 3 deletions(-)

diff --git a/grub-core/commands/bli.c b/grub-core/commands/bli.c
index 0b4e1259a..b77e393a0 100644
--- a/grub-core/commands/bli.c
+++ b/grub-core/commands/bli.c
@@ -192,6 +192,84 @@ set_loader_default_entry (void)
     }
 }
 
+/* Parse the timeout according to the Boot Loader Interface spec
+   for LoaderConfigTimeout and LoaderConfigTimeoutOneShot.
+   Return true when the timeout has been set. */
+static int
+parse_timeout_bli (const char* config_timeout, bool is_oneshot)
+{
+  unsigned int timeout;
+  /* When the timeout is set to menu-force or LoaderConfigTimeoutOneShot is
+     set to 0, show the menu indefinitely */
+  if (grub_strcmp (config_timeout, "menu-force") == 0
+          || (is_oneshot && grub_strcmp (config_timeout, "0") == 0))
+    {
+      grub_env_unset ("timeout");
+      grub_env_set ("timeout_style", "menu");
+      /* When set to 0 or to menu-hidden, don't show the menu but wait until 
the
+         timeout expires. Allow the user to interrupt the boot and show the 
menu */
+    } else if (grub_strcmp (config_timeout, "0") == 0
+           || grub_strcmp (config_timeout, "menu-hidden") == 0)
+    {
+      grub_menu_set_timeout (3);
+      grub_env_set ("timeout_style", "hidden");
+      /* When set to to menu-disabled, don't show the menu and boot the default
+         entry directly. Don't allow the user to interrupt the bootloader. */
+    } else if (grub_strcmp (config_timeout, "menu-disabled") == 0)
+    {
+      grub_env_set ("timeout", "0");
+      grub_env_set ("timeout_style", "disabled");
+    } else {
+      timeout = grub_strtoul (config_timeout, 0, 10);
+      if (grub_errno == GRUB_ERR_NONE)
+       {
+          /* In previous versions of bootctl, timeout is set to GRUB_UINT_MAX
+             instead of menu-force */
+         if (timeout == GRUB_UINT_MAX)
+           grub_env_unset ("timeout");
+         else
+           grub_menu_set_timeout (timeout);
+
+         grub_env_set ("timeout_style", "menu");
+       } else {
+         grub_errno = GRUB_ERR_NONE;
+          return false;
+       }
+    }
+
+    return true;
+}
+
+/* Read LoaderConfigTimeout and LoaderConfigTimeoutOneShot and update
+   timeout accordingly */
+static void
+set_timeout_from_loader_config (void)
+{
+  bool has_oneshot = false;
+  char* config_timeout = get_efivar ("LoaderConfigTimeoutOneShot");
+  if (config_timeout)
+  {
+    /* Remove its value, regardless if it is valid or not */
+    grub_efi_set_variable_to_string ("LoaderConfigTimeoutOneShot",
+           &bli_vendor_guid, "", 0);
+
+    has_oneshot = parse_timeout_bli (config_timeout, true);
+    grub_free (config_timeout);
+  }
+
+  if (has_oneshot)
+    return;
+
+  /* If there was no LoaderConfigTimeoutOneShot value or it was invalid,
+     read LoaderConfigTimeout */
+  config_timeout = get_efivar ("LoaderConfigTimeout");
+  if (!config_timeout)
+    return;
+
+  parse_timeout_bli (config_timeout, false);
+  grub_free (config_timeout);
+}
+
 GRUB_MOD_INIT (bli)
 {
   grub_efi_set_variable_to_string ("LoaderInfo", &bli_vendor_guid, 
PACKAGE_STRING,
@@ -200,6 +278,7 @@ GRUB_MOD_INIT (bli)
   set_loader_device_part_uuid ();
   set_loader_active_pcr_banks ();
   set_loader_default_entry ();
+  set_timeout_from_loader_config ();
   /* No error here is critical, other than being logged */
   grub_print_error ();
 }
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
index 569573011..e9738890a 100644
--- a/grub-core/normal/menu.c
+++ b/grub-core/normal/menu.c
@@ -44,7 +44,8 @@ grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t 
menu,
 enum timeout_style {
   TIMEOUT_STYLE_MENU,
   TIMEOUT_STYLE_COUNTDOWN,
-  TIMEOUT_STYLE_HIDDEN
+  TIMEOUT_STYLE_HIDDEN,
+  TIMEOUT_STYLE_DISABLED
 };
 
 struct timeout_style_name {
@@ -54,6 +55,7 @@ struct timeout_style_name {
   {"menu", TIMEOUT_STYLE_MENU},
   {"countdown", TIMEOUT_STYLE_COUNTDOWN},
   {"hidden", TIMEOUT_STYLE_HIDDEN},
+  {"disabled", TIMEOUT_STYLE_DISABLED},
   {NULL, 0}
 };
 
@@ -672,10 +674,11 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, 
int *notify_boot)
     }
 
   /* If timeout is 0, drawing is pointless (and ugly).  */
-  if (timeout == 0)
+  if (timeout == 0 || timeout_style == TIMEOUT_STYLE_DISABLED)
     {
       *auto_boot = 1;
-      *notify_boot = timeout_style != TIMEOUT_STYLE_HIDDEN;
+      *notify_boot = timeout_style != TIMEOUT_STYLE_HIDDEN
+                     && timeout_style != TIMEOUT_STYLE_DISABLED;
       return default_entry;
     }
 
-- 
2.53.0


++++++ 0005-bls_bumpcounter-Add-command-to-bump-boot-counter-for.patch ++++++
>From d5ac5c86c4014a6dedc47073ef305d227c38f65c Mon Sep 17 00:00:00 2001
From: Danilo Spinella <[email protected]>
Date: Thu, 12 Mar 2026 10:51:06 +0100
Subject: [PATCH 5/9] bls_bumpcounter: Add command to bump boot counter for BLS
 entries

---
 grub-core/Makefile.core.def          |   6 +
 grub-core/commands/bls_bumpcounter.c | 275 +++++++++++++++++++++++++++
 grub-core/normal/menu.c              |  23 +++
 include/grub/efi/filesystem.h        | 155 +++++++++++++++
 4 files changed, 459 insertions(+)
 create mode 100644 grub-core/commands/bls_bumpcounter.c
 create mode 100644 include/grub/efi/filesystem.h

Index: grub-2.14/grub-core/Makefile.core.def
===================================================================
--- grub-2.14.orig/grub-core/Makefile.core.def
+++ grub-2.14/grub-core/Makefile.core.def
@@ -868,6 +868,12 @@ module = {
   cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)';
 };
 
+ module = {
+  name = bls_bumpcounter;
+  efi = commands/bls_bumpcounter.c;
+  enable = efi;
+};
+
 module = {
   name = boot;
   common = commands/boot.c;
Index: grub-2.14/grub-core/commands/bls_bumpcounter.c
===================================================================
--- /dev/null
+++ grub-2.14/grub-core/commands/bls_bumpcounter.c
@@ -0,0 +1,275 @@
+/* bls.c - implementation of the boot loader spec */
+
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "grub/err.h"
+#include <grub/charset.h>
+#include <grub/extcmd.h>
+#include <grub/fs.h>
+#include <grub/env.h>
+#include <grub/lib/envblk.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/filesystem.h>
+
+#include <stddef.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+#define GRUB_BLS_CONFIG_PATH "\\loader\\entries\\"
+
+static const grub_guid_t grub_simple_file_system_guid =
+                               GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
+static const grub_guid_t bli_vendor_guid =
+                               GRUB_EFI_VENDOR_BOOT_LOADER_INTERFACE_GUID;
+
+/* Replace linux path delimiter (/) with EFI compatible (\) */
+static void
+use_efi_delimiter_for_path (char* s)
+{
+  char* tmp = grub_strchr(s, '/');
+  while (tmp != NULL)
+    {
+      *tmp++ = '\\';
+      tmp = grub_strchr(tmp, '/');
+    }
+}
+
+/* Calculate the new filename with the bumped counter */
+static char*
+bump_counter (char* entry)
+{
+  char *tmp = grub_strrchr (entry, '+');
+  int tries = -1, tries_left;
+  *tmp = '\0';
+  tries_left = grub_strtol (++tmp, (const char**) &tmp, 10);
+  /* The parsing succeeded */
+  if (tmp != NULL)
+    {
+      if (tries_left > 0)
+       {
+         tries_left--;
+       }
+      if (*tmp == '-')
+       {
+         tmp++;
+         tries = grub_strtol (tmp, (const char**) &tmp, 10);
+         if (tmp != NULL)
+           {
+             tries++;
+           } else {
+             tries = -1;
+           }
+       }
+    } else {
+      return NULL;
+    }
+
+  if (tries == -1)
+    {
+      /* This is the first try, rename accordingly */
+      return grub_xasprintf ("%s+%d-1.conf", entry, tries_left);
+    } else {
+      return grub_xasprintf ("%s+%d-%d.conf", entry, tries_left, tries);
+    }
+}
+
+static grub_err_t
+grub_cmd_bls_bumpcounter (grub_extcmd_context_t ctxt __attribute__ ((unused)),
+                         int argc, char **args)
+{
+  grub_efi_loaded_image_t *image;
+  grub_efi_file_info_t *file_info = NULL;
+  grub_efi_file_protocol_t *handle, *root;
+  grub_efi_simple_file_system_protocol_t *volume;
+  grub_efi_boot_services_t *bs;
+  grub_guid_t grub_efi_file_info_guid = GRUB_EFI_FILE_INFO_ID;
+  grub_efi_status_t err;
+  char *entry, *new_path = NULL, *old_path;
+  const char *blsdir;
+  grub_efi_uint64_t size;
+  grub_efi_char16_t *old_path16;
+
+  if (argc != 1) {
+    grub_dprintf ("bls_bumpcounter", "only one argument should be passed\n");
+    return GRUB_ERR_BAD_ARGUMENT;
+  }
+  entry = args[0];
+
+  grub_efi_set_variable_to_string ("LoaderEntrySelected",
+                                  &bli_vendor_guid, entry,
+                                  GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                  | GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
+
+  /* Look for the start of the boot count.
+     If no '+' symbol has been found, the boot counting isn't enabled for
+     the selected entry */
+  if (grub_strrchr (entry, '+') == NULL)
+    {
+      grub_dprintf ("bls_bumpcounter",
+                   "boot counting is not in effect for %s\n", entry);
+      return GRUB_ERR_NONE;
+    }
+
+  image = grub_efi_get_loaded_image (grub_efi_image_handle);
+
+  if (!image)
+    {
+      grub_dprintf ("bls_bumpcounter", "grub_efi_get_loaded_image failed\n");
+      return GRUB_ERR_BUG;
+    }
+
+  bs = grub_efi_system_table->boot_services;
+  err = bs->handle_protocol (image->device_handle,
+                            (void *) &grub_simple_file_system_guid, (void *) 
&volume);
+  if (err != GRUB_EFI_SUCCESS)
+    {
+      grub_dprintf ("bls_bumpcounter",
+                   "Cannot get handle to EFI_SIMPLE_FILE_SYSTEM_PROTOCOL: 
%lu\n",
+                   (unsigned long) err);
+      return GRUB_ERR_BAD_DEVICE; 
+    }
+  err = volume->OpenVolume (volume, &root);
+  if (err != GRUB_EFI_SUCCESS)
+    {
+      grub_dprintf ("bls_bumpcounter",
+             "Cannot open the volume: %lu\n", (unsigned long) err);
+      return GRUB_ERR_BAD_DEVICE;
+    }
+
+  blsdir = grub_env_get ("blsdir");
+  if (blsdir)
+    {
+      use_efi_delimiter_for_path ((char*) blsdir);
+    } else {
+        blsdir = GRUB_BLS_CONFIG_PATH;
+    }
+
+  old_path = grub_xasprintf ("%s%s", blsdir, entry);
+  grub_utf8_to_utf16_alloc (old_path, &old_path16, NULL);
+
+  err = root->Open (root, &handle, old_path16,
+                   GRUB_EFI_FILE_MODE_READ|GRUB_EFI_FILE_MODE_WRITE, 0);
+  grub_free (old_path16);
+  if (err != GRUB_EFI_SUCCESS)
+    {
+      grub_dprintf("bls_bumpcounter", "Cannot open the entry %s: %lu\n",
+                  old_path, (unsigned long) err);
+      grub_free (old_path);
+      return GRUB_ERR_BAD_DEVICE;
+    }
+  grub_free (old_path);
+
+  /* Get the file_info by allocating a fixed size that should be big enough for
+     most cases, and, if it fails, allocate a new one with the exact size
+     returned from GetInfo.
+     Reference: systemd:src/boot/efi/util.c =*/
+  size = offsetof (grub_efi_file_info_t, FileName)
+                  + 256U * sizeof (grub_efi_char16_t);
+  file_info = grub_malloc (size);
+  if (!file_info)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+      goto finish;
+    }
+  err = handle->GetInfo (handle, &grub_efi_file_info_guid, &size, file_info);
+  if (err == GRUB_EFI_BUFFER_TOO_SMALL)
+    {
+      grub_free(file_info);
+      /* When we bump the counter, it might happen that we increase the 
filename
+         length. Add the space for 2 more characters. (i.e. adding the boot 
done
+         part "-1") */
+      size += 2;
+      file_info = grub_malloc (size);
+      if (!file_info)
+       {
+         grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+         goto finish;
+       }
+      err = handle->GetInfo (handle, &grub_efi_file_info_guid,
+                            &size, file_info);
+    }
+
+  if (err != GRUB_EFI_SUCCESS)
+    {
+      grub_dprintf ("bls_bumpcounter",
+                   "Cannot get the file_info of the entry: %lu\n", (unsigned 
long) err);
+      goto finish;
+    }
+
+  new_path = bump_counter (entry);
+  if (!new_path)
+    goto finish;
+
+  grub_dprintf ("bls_bumpcounter", "renaming entry to %s\n", new_path);
+  grub_utf8_to_utf16 (file_info->FileName,
+                     size - offsetof (grub_efi_file_info_t, FileName),
+                     (grub_uint8_t*) new_path, grub_strlen (new_path), NULL);
+
+  err = handle->SetInfo (handle, &grub_efi_file_info_guid, size, file_info);
+
+  if (err != GRUB_EFI_SUCCESS)
+    {
+      grub_dprintf ("bls_bumpcounter", "Cannot rename file: %lu\n",
+                   (unsigned long) err);
+      goto finish;
+    }
+
+  handle->Flush (handle);
+  grub_dprintf ("bls_bumpcounter", "entry renamed\n");
+  handle->Close (handle);
+
+  char* loader_boot_count_path = grub_xasprintf("%s%s", blsdir, new_path);
+  grub_free(new_path);
+  grub_efi_set_variable_to_string("LoaderBootCountPath", &bli_vendor_guid,
+                                 loader_boot_count_path,
+                                 GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS
+                                 | GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
+  grub_free(loader_boot_count_path);
+
+  if (err != GRUB_EFI_SUCCESS)
+    {
+      goto finish;
+    }
+
+  grub_free(file_info);
+  return GRUB_ERR_NONE;
+
+finish:
+  grub_free(file_info);
+  return GRUB_ERR_BUG;
+}
+
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(blsbumpcounter)
+{
+  grub_dprintf ("bls_bumpcounter", "%s got here\n", __func__);
+  cmd = grub_register_extcmd ("bls_bumpcounter",
+                             grub_cmd_bls_bumpcounter,
+                             0,
+                             NULL,
+                             N_("Bump the boot entry counting."),
+                             NULL);
+}
+
+GRUB_MOD_FINI(blsbumpcounter)
+{
+  grub_unregister_extcmd (cmd);
+}
Index: grub-2.14/grub-core/normal/menu.c
===================================================================
--- grub-2.14.orig/grub-core/normal/menu.c
+++ grub-2.14/grub-core/normal/menu.c
@@ -231,6 +231,10 @@ grub_menu_execute_entry(grub_menu_entry_
   char *optr, *buf, *oldchosen = NULL, *olddefault = NULL;
   const char *ptr, *chosen, *def;
   grub_size_t sz = 0;
+#ifdef GRUB_MACHINE_EFI
+  char *args[] = { NULL };
+  char *filename;
+#endif
 
   if (entry->restricted)
     {
@@ -324,6 +328,26 @@ grub_menu_execute_entry(grub_menu_entry_
     grub_env_set ("default", ptr + 1);
   else
     grub_env_unset ("default");
+
+#ifdef GRUB_MACHINE_EFI
+  /* Check if this entry has been generated by blscfg */
+  if (entry->blsuki && entry->blsuki->filename)
+    {
+      filename = grub_strdup (entry->blsuki->filename);
+
+      if (filename == NULL)
+       grub_print_error ();
+      else
+       {
+         *args = filename;
+
+          /* Bump the boot counter of the BLS entry */
+         grub_command_execute ("bls_bumpcounter", 1, args);
+         grub_free (filename);
+       }
+    }
+#endif
+
 #ifdef GRUB_MACHINE_IEEE1275
   char *cas_entry_id = NULL;
   char *cas_entry_source;
Index: grub-2.14/include/grub/efi/filesystem.h
===================================================================
--- /dev/null
+++ grub-2.14/include/grub/efi/filesystem.h
@@ -0,0 +1,155 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_EFI_TPM_HEADER
+#define GRUB_EFI_TPM_HEADER 1
+
+#include <grub/efi/api.h>
+#include <grub/env.h>
+
+struct grub_efi_file_io_token {
+  grub_efi_event_t Event;
+  grub_efi_status_t Status;
+  grub_efi_uint64_t BufferSize;
+  void *Buffer;
+};
+
+typedef struct grub_efi_file_io_token grub_efi_file_io_token_t;
+
+
+struct grub_efi_file_protocol
+{
+  grub_efi_uint64_t Revision;
+
+  grub_efi_status_t
+  (__grub_efi_api *Open) (struct grub_efi_file_protocol *this,
+                 struct grub_efi_file_protocol **new_handle,
+                 grub_efi_char16_t *filename,
+                 grub_efi_uint64_t open_mode,
+                 grub_efi_uint64_t attributes);
+
+  grub_efi_status_t
+  (__grub_efi_api *Close) (struct grub_efi_file_protocol *this);
+
+  grub_efi_status_t
+  (__grub_efi_api *Delete) (struct grub_efi_file_protocol *this);
+
+  grub_efi_status_t
+  (__grub_efi_api *Read) (struct grub_efi_file_protocol *this,
+                 grub_efi_uint64_t *buffer_size,
+                 void *buffer);
+
+  grub_efi_status_t
+  (__grub_efi_api *Write) (struct grub_efi_file_protocol *this,
+                 grub_efi_uint64_t *buffer_size,
+                 void *buffer);
+
+  grub_efi_status_t
+  (__grub_efi_api *GetPosition) (struct grub_efi_file_protocol *this,
+                 grub_efi_uint64_t *position);
+
+  grub_efi_status_t
+  (__grub_efi_api *SetPosition) (struct grub_efi_file_protocol *this,
+                 grub_efi_uint64_t position);
+
+  grub_efi_status_t
+  (__grub_efi_api *GetInfo) (struct grub_efi_file_protocol *this,
+                 grub_guid_t *information_type,
+                 grub_efi_uint64_t *buffer_size,
+                 void *buffer);
+
+  grub_efi_status_t
+  (__grub_efi_api *SetInfo) (struct grub_efi_file_protocol *this,
+                 grub_guid_t *information_type,
+                 grub_efi_uint64_t buffer_size,
+                 void *buffer);
+
+  grub_efi_status_t
+  (__grub_efi_api *Flush) (struct grub_efi_file_protocol *this);
+
+  grub_efi_status_t
+  (__grub_efi_api *OpenEx) (struct grub_efi_file_protocol *this,
+                 struct grub_efi_file_protocol **new_handle,
+                 grub_efi_char16_t *filename,
+                 grub_efi_uint64_t open_mode,
+                 grub_efi_uint64_t attributes,
+                 grub_efi_file_io_token_t *token);
+
+  grub_efi_status_t
+  (__grub_efi_api *ReadEx) (struct grub_efi_file_protocol *this,
+                 grub_efi_file_io_token_t *token);
+
+  grub_efi_status_t
+  (__grub_efi_api *WriteEx) (struct grub_efi_file_protocol *this,
+                 grub_efi_file_io_token_t *token);
+
+  grub_efi_status_t
+  (__grub_efi_api *FlushEx) (struct grub_efi_file_protocol *this,
+                 grub_efi_file_io_token_t *token);
+};
+
+typedef struct grub_efi_file_protocol grub_efi_file_protocol_t;
+
+/*******************************************************
+  Open Modes
+ ******************************************************/
+#define GRUB_EFI_FILE_MODE_READ       0x0000000000000001
+#define GRUB_EFI_FILE_MODE_WRITE      0x0000000000000002
+#define GRUB_EFI_FILE_MODE_CREATE     0x8000000000000000
+
+/*******************************************************
+  File Attributes
+ ******************************************************/
+#define GRUB_EFI_FILE_READ_ONLY       0x0000000000000001
+#define GRUB_EFI_FILE_HIDDEN     0x0000000000000002
+#define GRUB_EFI_FILE_SYSTEM     0x0000000000000004
+#define GRUB_EFI_FILE_RESERVED 0x0000000000000008
+#define GRUB_EFI_FILE_DIRECTORY       0x0000000000000010
+#define GRUB_EFI_FILE_ARCHIVE   0x0000000000000020
+#define GRUB_EFI_FILE_VALID_ATTR      0x0000000000000037
+
+struct grub_efi_file_info {
+  grub_efi_uint64_t Size;
+  grub_efi_uint64_t FileSize;
+  grub_efi_uint64_t PhysicalSize;
+  grub_efi_time_t CreateTime;
+  grub_efi_time_t LastAccessTime;
+  grub_efi_time_t ModificationTime;
+  grub_efi_uint64_t Attribute;
+  grub_efi_char16_t FileName[];
+};
+
+typedef struct grub_efi_file_info grub_efi_file_info_t;
+
+#define GRUB_EFI_FILE_INFO_ID \
+ {0x09576e92,0x6d3f,0x11d2, \
+    {0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b} \
+ }
+
+struct grub_efi_simple_file_system_protocol
+{
+  grub_efi_uint64_t Revision;
+
+  grub_efi_status_t
+  (__grub_efi_api *OpenVolume) (struct grub_efi_simple_file_system_protocol 
*this,
+                               struct grub_efi_file_protocol **root);
+};
+
+typedef struct grub_efi_simple_file_system_protocol 
grub_efi_simple_file_system_protocol_t;
+
+
+#endif

++++++ 0006-bli-Add-support-for-LoaderFeatures.patch ++++++
>From f7cdf321c11fc10e257cf512bebaabca4d792d82 Mon Sep 17 00:00:00 2001
From: Danilo Spinella <[email protected]>
Date: Thu, 19 Mar 2026 10:25:36 +0100
Subject: [PATCH 6/9] bli: Add support for LoaderFeatures

---
 grub-core/commands/bli.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/grub-core/commands/bli.c b/grub-core/commands/bli.c
index d0fde76f0..29f9d8ef7 100644
--- a/grub-core/commands/bli.c
+++ b/grub-core/commands/bli.c
@@ -37,6 +37,29 @@ GRUB_MOD_LICENSE ("GPLv3+");
 
 static const grub_guid_t bli_vendor_guid = 
GRUB_EFI_VENDOR_BOOT_LOADER_INTERFACE_GUID;
 
+#define GRUB_EFI_LOADER_FEATURE_CONFIG_TIMEOUT          (1 << 0)
+#define GRUB_EFI_LOADER_FEATURE_CONFIG_TIMEOUT_ONE_SHOT (1 << 1)
+#define GRUB_EFI_LOADER_FEATURE_ENTRY_DEFAULT           (1 << 2)
+#define GRUB_EFI_LOADER_FEATURE_ENTRY_ONESHOT           (1 << 3)
+#define GRUB_EFI_LOADER_FEATURE_BOOT_COUNTING           (1 << 4)
+#define GRUB_EFI_LOADER_FEATURE_XBOOTLDR                (1 << 5)
+#define GRUB_EFI_LOADER_FEATURE_MENU_DISABLE            (1 << 13)
+
+static grub_err_t
+set_loader_features (void)
+{
+  static long loader_features =
+      GRUB_EFI_LOADER_FEATURE_CONFIG_TIMEOUT |
+      GRUB_EFI_LOADER_FEATURE_CONFIG_TIMEOUT_ONE_SHOT |
+      GRUB_EFI_LOADER_FEATURE_ENTRY_DEFAULT |
+      GRUB_EFI_LOADER_FEATURE_ENTRY_ONESHOT |
+      GRUB_EFI_LOADER_FEATURE_BOOT_COUNTING |
+      GRUB_EFI_LOADER_FEATURE_XBOOTLDR |
+      GRUB_EFI_LOADER_FEATURE_MENU_DISABLE;
+
+  return grub_efi_set_variable("LoaderFeatures", &bli_vendor_guid, 
&loader_features, sizeof(long));
+}
+
 static grub_err_t
 get_part_uuid (const char *device_name, char **part_uuid)
 {
@@ -281,6 +304,7 @@ GRUB_MOD_INIT (bli)
   set_loader_active_pcr_banks ();
   set_loader_default_entry ();
   set_timeout_from_loader_config ();
+  set_loader_features ();
   /* No error here is critical, other than being logged */
   grub_print_error ();
 }
-- 
2.53.0


++++++ 0007-blsuki-Fix-sorting-for-entries-with-boot-counting-en.patch ++++++
>From 5cf5c938a1ed621e5dcd91277ad856552434df98 Mon Sep 17 00:00:00 2001
From: Danilo Spinella <[email protected]>
Date: Thu, 19 Mar 2026 12:17:12 +0100
Subject: [PATCH 7/9] blsuki: Fix sorting for entries with boot counting
 enabled

Sort entries with boot counting enabled (ending with +x-y.conf)
and with 0 tries left below the rest.
---
 grub-core/commands/blsuki.c | 46 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/grub-core/commands/blsuki.c b/grub-core/commands/blsuki.c
index 2664a9fc4..8364ba9f4 100644
--- a/grub-core/commands/blsuki.c
+++ b/grub-core/commands/blsuki.c
@@ -251,6 +251,42 @@ blsuki_get_val (grub_blsuki_entry_t *entry, const char 
*keyname, int *last)
   return ret;
 }
 
+/* Return the tries left of an entry with boot counting enabled.
+   When boot counting is disabled, return -1. */
+static long
+tries_left (const char *filename)
+{
+  char *tries_left_str;
+  long ret = -1;
+  char *str = grub_strdup (filename);
+
+  if (str == NULL)
+    return -1;
+
+  /* Search for the start of the tries left, as per boot assessment */
+  tries_left_str = grub_strrchr (str, '+');
+
+  if (tries_left_str != NULL)
+    {
+      const char *end;
+      long tries;
+
+      ++tries_left_str;
+      tries = grub_strtol (tries_left_str, (const char **) &end, 10);
+
+      if (grub_errno == GRUB_ERR_NONE)
+       {
+         if (*end == '-' || *end == '.')
+           ret = tries;
+       }
+      else
+       grub_errno = GRUB_ERR_NONE;
+    }
+
+  grub_free (str);
+  return ret;
+}
+
 /*
  * Add a new grub_blsuki_entry_t struct to the entries list and sort it's
  * position on the list.
@@ -259,7 +295,7 @@ static grub_err_t
 blsuki_add_entry (grub_blsuki_entry_t *entry)
 {
   grub_blsuki_entry_t *e, *last = NULL;
-  int rc;
+  int rc, t1, t2;
 
   if (entries == NULL)
     {
@@ -274,6 +310,14 @@ blsuki_add_entry (grub_blsuki_entry_t *entry)
       if (rc == 0)
        return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("duplicate file: `%s'"), 
entry->filename);
 
+      /* Entries with 0 tries left should be put below the rest */
+      t1 = tries_left (entry->filename);
+      t2 = tries_left (e->filename);
+      if (t2 == 0 && t1 != 0)
+       rc = 1;
+      else if (t2 != 0 && t1 == 0)
+       rc = -1;
+
       if (rc > 0)
        {
          grub_dprintf ("blsuki", "Add entry with id \"%s\"\n", 
entry->filename);
-- 
2.53.0


++++++ 0008-blsuki-append-leftover-LoaderEntries.patch ++++++
>From 716f057d6f6addd15d1913d4b3a3f879863c5839 Mon Sep 17 00:00:00 2001
From: Michael Chang <[email protected]>
Date: Wed, 1 Apr 2026 12:41:13 +0200
Subject: [PATCH 8/9] blsuki: append leftover LoaderEntries

When merging new BLS entries with the previous LoaderEntries value,
entries that sort after all new items can remain pending in
prev_entries. Those entries were not copied into the output buffer, so
the EFI variable could lose trailing previous entries.

Append any unconsumed previous entries after the merge, verify that
enough UTF-16 space remains, and size the variable from the final write
pointer. This keeps the merged list complete and reports the written
buffer length correctly.

Signed-off-by: Michael Chang <[email protected]>
---
 grub-core/commands/blsuki.c | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/grub-core/commands/blsuki.c b/grub-core/commands/blsuki.c
index 8364ba9f4..298f04a98 100644
--- a/grub-core/commands/blsuki.c
+++ b/grub-core/commands/blsuki.c
@@ -1489,7 +1489,7 @@ set_bli_loader_entries (enum blsuki_cmd_type cmd_type)
   prev_entries = prev_entries_start;
   prev_entries_size = prev_entries_start_size;
   p = efi_entries;
-  remaining_size = size;
+  remaining_size = size + (prev_entries_start_size / sizeof (*efi_entries));
   /* Create a null separated list of all entries (with the extension removed) 
*/
   FOR_BLSUKI_ENTRIES (entry)
     {
@@ -1552,9 +1552,39 @@ set_bli_loader_entries (enum blsuki_cmd_type cmd_type)
        }
     }
 
+    /*
+     * Append any entries left unconsumed in prev_entries after the ordered
+     * merge above. Previous entries are only emitted immediately when they
+     * sort before the current new entry; otherwise they remain pending until
+     * here.
+     */
+    if (prev_entries_size != 0 && prev_entries != NULL)
+      {
+       grub_size_t remaining_entries_size;
+
+       remaining_entries_size = prev_entries_size / sizeof (*prev_entries);
+       /*
+        * remaining_size is tracked in UTF-16 code units, so compare it
+        * against the number of UTF-16 elements left in the previous buffer.
+        */
+       if (remaining_size < remaining_entries_size)
+         {
+           grub_free (prev_entries_start);
+           grub_free (efi_entries);
+           return grub_error (
+               GRUB_ERR_OUT_OF_RANGE,
+               "LoaderEntries buffer too small for previous entries");
+         }
+
+       grub_memcpy (p, prev_entries, prev_entries_size);
+       p += remaining_entries_size;
+       remaining_size -= remaining_entries_size;
+       prev_entries_size = 0;
+      }
+
   status = grub_efi_set_variable_with_attributes ("LoaderEntries", 
&bli_vendor_guid,
                                         efi_entries,
-                                        size * sizeof (grub_efi_char16_t) + 
prev_entries_start_size - prev_entries_size,
+                                        (p - efi_entries) * sizeof 
(*efi_entries),
                                         GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
                                         GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
   /* Record that we set the generated entries by this command to LoaderEntries 
*/
-- 
2.53.0


++++++ 0009-blsuki-conservative-UTF-8-buffer-size.patch ++++++
>From a5b58fdf1f775f12c7560603d729f0415f47a4c1 Mon Sep 17 00:00:00 2001
From: Michael Chang <[email protected]>
Date: Wed, 1 Apr 2026 12:44:29 +0200
Subject: [PATCH 9/9] blsuki: conservative UTF-8 buffer size

To be on safe side, use GRUB_MAX_UTF8_PER_UTF16 as UTF-8 for non ascii
characters can be up to 4 bytes.
---
 grub-core/commands/blsuki.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/grub-core/commands/blsuki.c b/grub-core/commands/blsuki.c
index 298f04a98..adc87207e 100644
--- a/grub-core/commands/blsuki.c
+++ b/grub-core/commands/blsuki.c
@@ -1516,11 +1516,30 @@ set_bli_loader_entries (enum blsuki_cmd_type cmd_type)
          if (prev_entries_size != 0 && prev_entries)
            {
              do {
+               grub_size_t prev_entry_size;
+
                tmp16 = prev_entries;
                len16 = 0;
                while (*tmp16++ != '\0')
                    len16++;
-               prev_entry = grub_malloc (len16 + 1);
+
+               if (grub_mul (len16, GRUB_MAX_UTF8_PER_UTF16, &prev_entry_size) 
||
+                   grub_add (prev_entry_size, 1, &prev_entry_size))
+                 {
+                   grub_free (prev_entries_start);
+                   grub_free (efi_entries);
+                   return grub_error (GRUB_ERR_OUT_OF_RANGE,
+                                      "LoaderEntries entry is too large");
+                 }
+
+               prev_entry = grub_malloc (prev_entry_size);
+               if (prev_entry == NULL)
+                 {
+                   grub_free (prev_entries_start);
+                   grub_free (efi_entries);
+                   return grub_errno;
+                 }
+
                *grub_utf16_to_utf8 ((grub_uint8_t*) prev_entry, prev_entries, 
len16) = '\0';
                rc = filevercmp (prev_entry, entry->filename);
                if (rc == 0)
-- 
2.53.0



++++++ grub2-btrfs-01-add-ability-to-boot-from-subvolumes.patch ++++++
--- /var/tmp/diff_new_pack.hIjhwA/_old  2026-04-30 20:25:57.031896548 +0200
+++ /var/tmp/diff_new_pack.hIjhwA/_new  2026-04-30 20:25:57.035896712 +0200
@@ -25,6 +25,9 @@
   * Fix gcc-12 error: the comparison will always evaluate as 'true' for the
     address of 'label' will never be NULL [-Werror=address]
 
+v3:
+  * Check find_pathname() in grub_cmd_btrfs_list_subvols() and return an error
+    on failure
 ---
 
  grub-core/fs/btrfs.c |  561 
+++++++++++++++++++++++++++++++++++++++++++++++++--
@@ -372,7 +375,7 @@
  
    grub_btrfs_unmount (data);
  
-@@ -2431,6 +2638,248 @@
+@@ -2431,6 +2638,253 @@
  }
  #endif
  
@@ -578,7 +581,12 @@
 +        }
 +        buf[elemsize] = 0;
 +
-+      find_pathname(data, ref->dirid, fs_root, ref->name, &p);
++      err = find_pathname(data, ref->dirid, fs_root, ref->name, &p);
++      if (err)
++        {
++          r = -err;
++          break;
++        }
 +
 +      if (print)
 +        {
@@ -621,7 +629,7 @@
  static struct grub_fs grub_btrfs_fs = {
    .name = "btrfs",
    .fs_dir = grub_btrfs_dir,
-@@ -2446,13 +2895,89 @@
+@@ -2446,13 +2900,89 @@
  #endif
  };
  

++++++ grub2-btrfs-09-get-default-subvolume.patch ++++++
--- /var/tmp/diff_new_pack.hIjhwA/_old  2026-04-30 20:25:57.087898846 +0200
+++ /var/tmp/diff_new_pack.hIjhwA/_new  2026-04-30 20:25:57.091899011 +0200
@@ -3,9 +3,15 @@
   * Use overflow checking primitives where the arithmetic expression for
     buffer allocations may include unvalidated data
 
+v2:
+  * Check find_pathname() in grub_btrfs_get_parent_subvol_path() and return
+    an error on failure
+  * Use get_fs_root() with offset -1 in grub_btrfs_get_parent_subvol_path() so
+    lower_bound() can find the highest-offset ROOT_ITEM for the subvolume id
+
 --- a/grub-core/fs/btrfs.c
 +++ b/grub-core/fs/btrfs.c
-@@ -3104,6 +3104,254 @@
+@@ -3146,6 +3146,260 @@
    return 0;
  }
  
@@ -70,7 +76,7 @@
 +  ref = (struct grub_btrfs_root_ref *)buf;
 +
 +  err = get_fs_root(data, data->sblock.root_tree, grub_le_to_cpu64 
(key_out.offset),
-+                    0, &fs_root);
++                    -1, &fs_root);
 +  if (err)
 +    {
 +      grub_free(buf);
@@ -78,7 +84,13 @@
 +      return err;
 +    }
 +
-+  find_pathname(data, grub_le_to_cpu64 (ref->dirid), fs_root, ref->name, 
&parent_path);
++  err = find_pathname(data, grub_le_to_cpu64 (ref->dirid), fs_root, 
ref->name, &parent_path);
++  if (err)
++    {
++      grub_free(buf);
++      free_iterator(&desc);
++      return err;
++    }
 +
 +  if (child_path)
 +    {
@@ -260,7 +272,7 @@
  static struct grub_fs grub_btrfs_fs = {
    .name = "btrfs",
    .fs_dir = grub_btrfs_dir,
-@@ -3122,6 +3370,7 @@
+@@ -3164,6 +3418,7 @@
  static grub_command_t cmd_info;
  static grub_command_t cmd_mount_subvol;
  static grub_extcmd_t cmd_list_subvols;
@@ -268,7 +280,7 @@
  
  static char *
  subvolid_set_env (struct grub_env_var *var __attribute__ ((unused)),
-@@ -3192,6 +3441,11 @@
+@@ -3235,6 +3490,11 @@
                                         "[-p|-n] [-o var] DEVICE",
                                         "Print list of BtrFS subvolumes on "
                                         "DEVICE.", options);

Reply via email to