Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package sdbootutil for openSUSE:Factory 
checked in at 2026-03-04 20:59:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/sdbootutil (Old)
 and      /work/SRC/openSUSE:Factory/.sdbootutil.new.561 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "sdbootutil"

Wed Mar  4 20:59:37 2026 rev:93 rq:1336011 version:1+git20260303.90d816d

Changes:
--------
--- /work/SRC/openSUSE:Factory/sdbootutil/sdbootutil.changes    2026-02-11 
18:47:52.030907237 +0100
+++ /work/SRC/openSUSE:Factory/.sdbootutil.new.561/sdbootutil.changes   
2026-03-04 20:59:41.306728375 +0100
@@ -1,0 +2,28 @@
+Tue Mar 03 10:21:30 UTC 2026 - Alberto Planas Dominguez <[email protected]>
+
+- Update to version 1+git20260303.90d816d:
+  * Allow predicted PCRs to be empty
+  * Use grubenv for set-timeout (bsc#1258944)
+
+-------------------------------------------------------------------
+Wed Feb 25 13:00:27 UTC 2026 - Alberto Planas Dominguez <[email protected]>
+
+- Update to version 1+git20260225.fe2f59b (bsc#1258241):
+  * Use pcrlock predict to filter policy PCRs
+  * Drop hack to drop PCR9 using shift component
+  * Add sdbootutil config file
+  * Force back device for encypted rootfs
+  * Store backup under service ID (CVE-2026-25701)
+
+-------------------------------------------------------------------
+Thu Feb 19 13:23:48 UTC 2026 - Alberto Planas Dominguez <[email protected]>
+
+- Update to version 1+git20260219.db678d7:
+  * Use boot loader's config file only when required
+  * Do not generate predictions if no boot entries
+  * Warn when no default entry is found
+  * Add rootfs and rootfs-data parameters
+  * Redirect stderr for findmnt
+  * sdbootutil.spec: Drop obsolete dependency on dialog
+
+-------------------------------------------------------------------

Old:
----
  sdbootutil-1+git20260210.81c4815.obscpio

New:
----
  sdbootutil-1+git20260303.90d816d.obscpio

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

Other differences:
------------------
++++++ sdbootutil.spec ++++++
--- /var/tmp/diff_new_pack.8LiqUZ/_old  2026-03-04 20:59:42.546779556 +0100
+++ /var/tmp/diff_new_pack.8LiqUZ/_new  2026-03-04 20:59:42.546779556 +0100
@@ -18,7 +18,7 @@
 
 %global rustflags '-Clink-arg=-Wl,-z,relro,-z,now'
 Name:           sdbootutil
-Version:        1+git20260210.81c4815
+Version:        1+git20260303.90d816d
 Release:        0
 Summary:        Bootctl wrapper for BLS boot loaders
 License:        MIT
@@ -31,7 +31,6 @@
 BuildRequires:  libopenssl-devel
 BuildRequires:  systemd-rpm-macros
 Requires:       %{name}-dracut-measure-pcr
-Requires:       dialog
 Requires:       dracut-pcr-signature
 Requires:       efibootmgr
 Requires:       jq

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.8LiqUZ/_old  2026-03-04 20:59:42.618782527 +0100
+++ /var/tmp/diff_new_pack.8LiqUZ/_new  2026-03-04 20:59:42.622782693 +0100
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/openSUSE/sdbootutil.git</param>
-              <param 
name="changesrevision">81c48154d681e5d93625629081fe66aa838e8095</param></service></servicedata>
+              <param 
name="changesrevision">90d816d884019f7ffa0dc7b8e1dc866bfe7f922a</param></service></servicedata>
 (No newline at EOF)
 

++++++ sdbootutil-1+git20260210.81c4815.obscpio -> 
sdbootutil-1+git20260303.90d816d.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sdbootutil-1+git20260210.81c4815/sdbootutil 
new/sdbootutil-1+git20260303.90d816d/sdbootutil
--- old/sdbootutil-1+git20260210.81c4815/sdbootutil     2026-02-10 
13:47:27.000000000 +0100
+++ new/sdbootutil-1+git20260303.90d816d/sdbootutil     2026-03-03 
11:19:37.000000000 +0100
@@ -43,6 +43,8 @@
 arg_no_measure_pcr=
 arg_measure_pcr=
 arg_pcr=
+arg_rootfs=
+arg_rootfs_data=
 arg_force=
 have_snapshots=
 # for x in vmlinuz image vmlinux linux bzImage uImage Image zImage; do
@@ -76,7 +78,7 @@
 
 rollback=()
 
-declare -g -A eventlog
+declare -A eventlog
 
 tmpdir=$(mktemp -d -t sdbootutil.XXXXXX)
 cleanup()
@@ -138,6 +140,10 @@
                  --pcr                 Comma seperated list of PCRs to enroll
                  --devices             Comma separated list of devices to 
enroll or unenroll
                                        (by default all (not ignored) devices 
are [un]enrolled)
+                 --rootfs              During bootloader installation, select 
the kind of 'root'
+                                       valid selectors
+                                       (uuid, partuuid, label, partlabel, 
device)
+                 --rootfs-data         Extra data when --rootfs is used
                  --force               Force certain operations inside a 
transaction
                  -v, --verbose         More verbose output
                  --start-trace-code    Create /var/log/sdbootutil.log to trace 
the code.
@@ -298,16 +304,82 @@
 
 is_config_file()
 {
-       [ -e /usr/etc/default/fde-tools ] ||
+       [ -e /usr/etc/default/sdbootutil ] ||
+               [ -e /etc/default/sdbootutil ] ||
+               [ -e /usr/etc/default/fde-tools ] ||
                [ -e /etc/default/fde-tools ] ||
                [ -e /etc/sysconfig/fde-tools ]
 }
 
+set_default_config_values()
+{
+       FDE_SEAL_PCR_LIST="$arg_pcr"
+       if is_installed && [ -z "${FDE_SEAL_PCR_LIST}" ]; then
+               if systemd-detect-virt -q; then
+                       info "Virtualized systemd detected 
($(systemd-detect-virt)). Dropping PCR0 and PCR2"
+                       FDE_SEAL_PCR_LIST=""
+               else
+                       FDE_SEAL_PCR_LIST="0,2,"
+               fi
+               if is_sdboot; then
+                       FDE_SEAL_PCR_LIST+="4,7,9"
+               elif is_grub2_bls; then
+                       FDE_SEAL_PCR_LIST+="4,7,8,9"
+               else
+                       err "Bootloader not detected"
+               fi
+       fi
+
+       if is_rootfs_crypt; then
+               # `measure-pcr-validator` (PRC15) protect from
+               # impostor LUKS2 volumes, as it measures the volume
+               # key.  But if there is a volume in a non-encrypted
+               # device (USB, for example) that has the same metadata
+               # (referenced by /etc/fstab) as the internal volume in
+               # the encrypted root device, then there is a chance
+               # that this will get mounted in /sysroot.  systemd can
+               # measure elements from the file system (like UUID or
+               # /etc/machine-id) via [email protected],
+               # but this data is public and can be replicated
+               #
+               # See bsc#1229934 for more details
+               ROOTFS="device"
+       else
+               ROOTFS="uuid"
+       fi
+       ROOTFS="${arg_rootfs:-$ROOTFS}"
+}
+
+create_default_config_file()
+{
+       ! is_config_file || return 0
+
+       set_default_config_values
+       cat <<-EOF > /etc/default/sdbootutil
+       # Default sdbootutil configuration file generated automatically
+
+       # List of PCRs.  For VMs PCRs 0 and 2 are dropped
+       FDE_SEAL_PCR_LIST="$FDE_SEAL_PCR_LIST"
+
+       # Parameter used in the cmdline to find the root (device, [part]uuid, 
[part]label)
+       # For encrypted devices it is forced "device"
+       ROOTFS="$ROOTFS"
+       EOF
+}
+
 load_config_file()
 {
        local f
-       # Some old installations have /etc/sysconfig/fde-tools
-       for f in /usr/etc/default/fde-tools /etc/default/fde-tools 
/etc/sysconfig/fde-tools; do
+
+       set_default_config_values
+
+       # Prioritize sdbootutil configuration file, and use fde-tools
+       # as a fallback
+       for f in /usr/etc/default/sdbootutil \
+                        /etc/default/sdbootutil \
+                        /usr/etc/default/fde-tools \
+                        /etc/default/fde-tools \
+                        /etc/sysconfig/fde-tools; do
                [ ! -e "$f" ] || {
                        # shellcheck disable=SC1090
                        . "$f"
@@ -315,6 +387,16 @@
                        dbg_cat "$f"
                }
        done
+
+       # Force back "device" for ROOTFS if is encrypted
+       if is_rootfs_crypt; then
+               [ "$ROOTFS" = "device" ] || info "Fix the 
/etc/default/sdbootutil to set ROOTFS as 'device'"
+               ROOTFS="device"
+       fi
+
+       # If arguments are passed, use them
+       FDE_SEAL_PCR_LIST="${arg_pcr:-$FDE_SEAL_PCR_LIST}"
+       ROOTFS="${arg_rootfs:-$ROOTFS}"
 }
 
 is_secure_boot()
@@ -368,7 +450,7 @@
 
 is_transactional()
 {
-       findmnt --fstab / -O ro > /dev/null
+       findmnt --fstab / -O ro &> /dev/null
 }
 
 keyctl_add_with_timeout()
@@ -458,14 +540,71 @@
        dbg_var "parent_snapshot"
 }
 
+is_rootfs_crypt()
+{
+       local device
+       read -r device < <(findmnt / -v -r -n -o SOURCE 2> /dev/null)
+       [ -n "$device" ] && [ "$(lsblk --noheadings -o TYPE "$device")" = 
"crypt" ]
+}
+
+get_rootfs()
+{
+       local rootfs_data
+
+       case "$ROOTFS" in
+               uuid) read -r rootfs_data < <(findmnt / -v -r -n -o UUID 2> 
/dev/null) ;;
+               label) read -r rootfs_data < <(findmnt / -v -r -n -o LABEL 2> 
/dev/null) ;;
+               partuuid) read -r rootfs_data < <(findmnt / -v -r -n -o 
PARTUUID 2> /dev/null) ;;
+               partlabel) read -r rootfs_data < <(findmnt / -v -r -n -o 
PARTLABEL 2> /dev/null) ;;
+               device) read -r rootfs_data < <(findmnt / -v -r -n -o SOURCE 2> 
/dev/null) ;;
+               *)
+                       info "Can't determine rootfs ($ROOTFS). Using UUID as 
default"
+                       ROOTFS="uuid"
+                       read -r rootfs_data < <(findmnt / -v -r -n -o UUID 2> 
/dev/null)
+                       ;;
+       esac
+       rootfs_data="${arg_rootfs_data:-$rootfs_data}"
+
+       if [ "$ROOTFS" = "device" ]; then
+               echo "$rootfs_data"
+       else
+               echo "${ROOTFS^^}=$rootfs_data"
+       fi
+}
+
+get_all_rootfs()
+{
+       local rootfs rootfs_data
+
+       read -r rootfs_data < <(findmnt / -v -r -n -o SOURCE)
+       rootfs="$rootfs_data"
+
+       read -r rootfs_data < <(findmnt / -v -r -n -o UUID)
+       [ -z "$rootfs_data" ] || rootfs="$rootfs|UUID=$rootfs_data"
+
+       read -r rootfs_data < <(findmnt / -v -r -n -o LABEL)
+       [ -z "$rootfs_data" ] || rootfs="$rootfs|LABEL=$rootfs_data"
+
+       read -r rootfs_data < <(findmnt / -v -r -n -o PARTUUID)
+       [ -z "$rootfs_data" ] || rootfs="$rootfs|PARTUUID=$rootfs_data"
+
+       read -r rootfs_data < <(findmnt / -v -r -n -o PARTLABEL)
+       [ -z "$rootfs_data" ] || rootfs="$rootfs|PARTLABEL=$rootfs_data"
+
+       echo "$rootfs"
+}
+
 sedrootflags()
 {
        local subvol="$1"
+       local root_param
+       root_param="$(get_rootfs)"
+
        # - Delete everything before BOOT_IMAGE= and initrd=
        #   (see https://github.com/openSUSE/sdbootutil/issues/182)
        # - Delete BOOT_IMAGE= and initrd=
-       # - Replace or add root= to refers to UUID or mapped device
-       #   (if encrypted)
+       # - Replace or add root= to refers to [PART]{UUID, LABEL}, or
+       #   mapped device
        # - Replace or add rootflags to point at correct subvolume
        # - Replace or add systemd.machine-id to match current
        #   machine-id
@@ -481,8 +620,6 @@
        # already there). Since we always operate on the same line,
        # "empty" t jumps are used to reset the condition after very
        # s///.
-       local root_param="UUID=$root_uuid"
-       [ -z "$root_device_is_crypt" ] || root_param="$root_device"
        local sed_arguments=("-e s/[ \t]\+/ /g"
                "-e s/^.*\(initrd=[^ ]*\|BOOT_IMAGE=[^ ]*\)\s*/\1 /"
                "-e s/\<\(BOOT_IMAGE\|initrd\)=[^ ]* \?//"
@@ -493,6 +630,7 @@
        sed "${sed_arguments[@]}"
 }
 
+
 entry_filter=("cat")
 update_entries()
 {
@@ -507,8 +645,11 @@
        local subvol="$1"
        local ext="${2:-}"
 
+       local root
+       root="$(get_all_rootfs)"
+
        [ -z "$ext" ] || ext="|$ext"
-       update_entries jq 
"[.[]|select(has(\"options\"))|select(.options|test(\"root=(?:UUID=$root_uuid|$root_device)
 .*rootflags=subvol=$subvol\")$ext)]"
+       update_entries jq 
"[.[]|select(has(\"options\"))|select(.options|test(\"root=(?:$root) 
.*rootflags=subvol=$subvol\")$ext)]"
 }
 
 update_entries_for_snapshot()
@@ -525,7 +666,10 @@
 
 update_entries_for_this_system()
 {
-       update_entries jq 
"[.[]|select(has(\"options\"))|select(.options|test(\"root=(?:UUID=$root_uuid|$root_device)\"))]"
+       local root
+       root="$(get_all_rootfs)"
+
+       update_entries jq 
"[.[]|select(has(\"options\"))|select(.options|test(\"root=(?:$root)\"))]"
 }
 
 entry_conf_file()
@@ -640,7 +784,11 @@
        # grubenv value)
        local default
        default="$(get_default_bootctl)"
-       set_default_entry "$default"
+       if [ -z "$default" ]; then
+               warn "Can't determine the new default entry"
+       else
+               set_default_entry "$default"
+       fi
 
        # This action will require to update the PCR predictions
        update_predictions=1
@@ -879,7 +1027,7 @@
        # one extra snapshot if it is passed as a parameter, that
        # refers to the snapshot from where we are installing the
        # kernel
-       declare -A snapshots
+       local -A snapshots
        [ -z "$snapshot" ] || snapshots["$snapshot"]=1
        [ -z "$root_snapshot" ] || snapshots["$root_snapshot"]=1
        local id
@@ -1754,13 +1902,14 @@
        fi
 
        # Create boot menu entry if it does not exist
-       local drive partno
-       read -r drive partno _ < <(boot_root_drive_partno_dseq)
-       local escaped_entry="${entry//\//\\\\}"
-       [ -n "$arg_no_variables" ] || [ -n "$arg_portable" ] || efibootmgr | 
grep -q "Boot.*${boot_manager}.*${escaped_entry}" || efibootmgr -q --create 
--disk "$drive" --part "$partno" --label "${boot_manager} ($bldr_name)" 
--loader "$entry" || true
+       if [ -z "$arg_no_variables" ] && [ -z "$arg_portable" ] && mountpoint 
-q "$boot_root"; then
+               local drive partno
+               read -r drive partno _ < <(boot_root_drive_partno_dseq)
+
+               local escaped_entry="${entry//\//\\\\}"
+               efibootmgr | grep -q "Boot.*${boot_manager}.*${escaped_entry}" 
|| efibootmgr -q --create --disk "$drive" --part "$partno" --label 
"${boot_manager} ($bldr_name)" --loader "$entry" || true
 
-       # Make it the first option
-       if [ -z "$arg_no_variables" ] && [ -z "$arg_portable" ]; then
+               # Make it the first option
                local boot_order
                boot_order="$(efibootmgr | grep BootOrder)"
                boot_order="${boot_order#BootOrder: }"
@@ -1815,13 +1964,27 @@
        mv "$boot_root/loader/random-seed.new" "$boot_root/loader/random-seed"
 }
 
+has_efivars()
+{
+       [ -d /sys/firmware/efi/efivars ]
+}
+
 bli_efi_var_get()
 {
        # BLI uses this vendor UUID
        local 
efi_var="/sys/firmware/efi/efivars/${1:?}-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"
-       if [ -e "$efi_var" ]; then
-               dd "if=$efi_var" bs=2 skip=2 conv=lcase status=none | tr -d '\0'
-       fi
+       [ ! -e "$efi_var" ] || dd "if=$efi_var" bs=2 skip=2 conv=lcase 
status=none | tr -d '\0'
+}
+
+bli_efi_var_set()
+{
+       # BLI uses this vendor UUID
+       local 
efi_var="/sys/firmware/efi/efivars/${1:?}-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"
+       local value="${2:?}"
+       has_efivars || return 1
+       [ -e "$efi_var" ] && chattr -i "$efi_var"
+       echo -ne "\x07\x00${value}\x00" | iconv -t UTF-16LE > "$efi_var"
+       chattr +i "$efi_var"
 }
 
 loader_conf_set()
@@ -1883,22 +2046,24 @@
 set_default_sdboot()
 {
        local id="${1:?}"
-       if ! bootctl set-default "$id" > "$tmpfile" 2>&1; then
-               if grep -q "Failed to update EFI variable" "$tmpfile" ||
-                               grep -q "Not booted with a supported boot 
loader" "$tmpfile" ||
-                               grep -q "Not booted with UEFI" "$tmpfile"; then
-                       loader_conf_set "default" "$id"
-               else
-                       err "$(cat "$tmpfile")"
-               fi
+
+       if ! has_efivars || [ -n "$arg_no_variables" ]; then
+               loader_conf_set "default" "$id"
+       elif ! bli_efi_var_set "LoaderEntryDefault" "$id"; then
+               warn "EFI variable LoaderEntryDefault cannot be set.  Falling 
back to configuration file"
+               loader_conf_set "default" "$id"
        fi
 }
 
 set_default_grub2_bls()
 {
        local id="${1:?}"
-       set_default_sdboot "$id"
-       grubenv_set "default" "$id"
+       if systemd-analyze compare-versions "$(bootloader_version)" "<" "2.13" 
|| ! has_efivars || [ -n "$arg_no_variables" ]; then
+               grubenv_set "default" "$id"
+       elif ! bli_efi_var_set "LoaderEntryDefault" "$id"; then
+               warn "EFI variable LoaderEntryDefault cannot be set.  Falling 
back to configuration file"
+               grubenv_set "default" "$id"
+       fi
 }
 
 set_default_entry()
@@ -1955,8 +2120,9 @@
 get_default_grub2_bls()
 {
        local val
-       val="$(grubenv_get "default")"
-       [ -n "$val" ] || val="$(get_default_sdboot)"
+       val="$(bli_efi_var_get "LoaderEntryDefault")"
+       [ -n "$val" ] || val="$(grubenv_get "default")"
+       [ -n "$val" ] || val="$(get_default_bootctl)"
        [ -z "$val" ] || echo "$val"
 }
 
@@ -1974,25 +2140,51 @@
 set_timeout_sdboot()
 {
        local timeout="${1:?}"
+       # `bootctl set-timeout menu-hidden` writes "0", and
+       # "menu-disabled" write the full text.  In both cases the menu
+       # is hidden.
+       #
+       # `bootctl set-timeout menu-force` writes 2^32-1 in the EFI
+       # variable (fix needs to be backported) (bsc#1258944)
+       [ "$timeout" = "0" ] && timeout="menu-disabled"
        [ "$timeout" = "-1" ] && timeout="menu-force"
-       if ! bootctl set-timeout "$timeout" > "$tmpfile" 2>&1; then
-               if grep -q "Failed to update EFI variable" "$tmpfile" ||
-                               grep -q "Not booted with a supported boot 
loader" "$tmpfile" ||
-                               grep -q "Not booted with UEFI" "$tmpfile"; then
-                       loader_conf_set "timeout" "$timeout"
-               else
-                       err "$(cat "$tmpfile")"
-               fi
+
+       # `bootctl set-timeout menu-force` writes 2^32-1 in the EFI
+       # variable (fix needs to be backported) (bsc#1258944)
+       if ! has_efivars || [ -n "$arg_no_variables" ]; then
+               loader_conf_set "timeout" "$timeout"
+       elif ! bli_efi_var_set "LoaderConfigTimeout" "$timeout"; then
+               warn "EFI variable LoaderConfigTimeout cannot be set.  Falling 
back to configuration file"
+               loader_conf_set "timeout" "$timeout"
        fi
 }
 
 set_timeout_grub2_bls()
 {
        local timeout="${1:?}"
-       set_timeout_sdboot "$timeout"
-       [ "$timeout" = "menu-disabled" ] || [ "$timeout" = "menu-hidden" ] && 
timeout=0
-       [ "$timeout" = "menu-force" ] && timeout=-1
-       grubenv_set "timeout" "$timeout"
+       # `bootctl set-timeout menu-hidden` writes "0", and
+       # "menu-disabled" write the full text.  In both cases the menu
+       # is hidden.
+       #
+       # `bootctl set-timeout menu-force` writes 2^32-1 in the EFI
+       # variable (fix needs to be backported) (bsc#1258944)
+       #
+       # We map the same string that works in grub2-bls with the
+       # downstream patch
+       [ "$timeout" = "menu-disabled" ] && timeout="menu-hidden"
+       [ "$timeout" = "0" ] && timeout="menu-hidden"
+       [ "$timeout" = "-1" ] && timeout="menu-force"
+
+       if systemd-analyze compare-versions "$(bootloader_version)" "<" "2.13" 
|| ! has_efivars || [ -n "$arg_no_variables" ]; then
+               [ "$timeout" = "menu-disabled" ] || [ "$timeout" = 
"menu-hidden" ] && timeout=0
+               [ "$timeout" = "menu-force" ] && timeout=-1
+               grubenv_set "timeout" "$timeout"
+       elif ! bli_efi_var_set "LoaderConfigTimeout" "$timeout"; then
+               warn "EFI variable LoaderConfigTimeout cannot be set.  Falling 
back to configuration file"
+               [ "$timeout" = "menu-disabled" ] || [ "$timeout" = 
"menu-hidden" ] && timeout=0
+               [ "$timeout" = "menu-force" ] && timeout=-1
+               grubenv_set "timeout" "$timeout"
+       fi
 }
 
 set_timeout()
@@ -2016,16 +2208,18 @@
        local val
        val="$(bli_efi_var_get "LoaderConfigTimeout")"
        [ -n "$val" ] || val="$(loader_conf_get "timeout")"
-       if [ "$val" = 4294967295 ]; then
-               val=-1
-       fi
+       [ "$val" = "menu-disabled" ] || [ "$val" = "menu-hidden" ] && val=0
+       [ "$val" = 4294967295 ] || [ "$val" = "menu-force" ] && val=-1
        [ -z "$val" ] || echo "$val"
 }
 
 get_timeout_grub2_bls()
 {
        local val
-       val="$(grubenv_get "timeout")"
+       val="$(bli_efi_var_get "LoaderConfigTimeout")"
+       [ -n "$val" ] || val="$(grubenv_get "timeout")"
+       [ "$val" = "menu-disabled" ] || [ "$val" = "menu-hidden" ] && val=0
+       [ "$val" = 4294967295 ] || [ "$val" = "menu-force" ] && val=-1
        [ -z "$val" ] || echo "$val"
 }
 
@@ -2282,7 +2476,7 @@
        #
        # When using systemd-boot or GRUB2-BLS >= 2.14, the cmdline is
        # send to the kernel via UEFI with null termination (double
-       # \0, as is UTF-16 enconding), but this is missing in
+       # \x00, as is UTF-16 enconding), but this is missing in
        # GRUB2-BLS <= 2.12
        echo -n "$cmdline" > "$tmpdir/cmdline"
        if is_sdboot; then
@@ -2324,7 +2518,7 @@
        if is_sdboot; then
                # We cannot use lock-kernel-cmdline, as it ignore
                # --pcr=12, and assign PCR 9 in any case
-               echo -ne "$cmdline\0" > "$tmpdir/cmdline"
+               echo -ne "$cmdline\x00" > "$tmpdir/cmdline"
                iconv -t UTF-16LE -o "$tmpdir/cmdline.utf16" "$tmpdir/cmdline"
                pcrlock \
                        lock-raw \
@@ -2405,10 +2599,12 @@
                locks+=("$tmpdir/entry-$n.pcrlock")
        done
        mkdir -p /var/lib/pcrlock.d/643-grub2-bls-entry-files.pcrlock.d
-       jq --slurp '{"records": [.[].records[0]]}' \
-          "${locks[@]}" \
-          > 
"/var/lib/pcrlock.d/643-grub2-bls-entry-files.pcrlock.d/generated$suffix.pcrlock"
-       rm "${locks[@]}"
+       [ "${#locks[@]}" -eq 0 ] || {
+               jq --slurp '{"records": [.[].records[0]]}' \
+                  "${locks[@]}" \
+                  > 
"/var/lib/pcrlock.d/643-grub2-bls-entry-files.pcrlock.d/generated$suffix.pcrlock"
+               rm "${locks[@]}"
+       }
 }
 
 pcrlock_sdboot()
@@ -2620,20 +2816,16 @@
        # will be asked.  To resolve this we can drop PCR#9 when there
        # is a new kernel and allow the rollback without a password,
        # and lock on PCR#9 during boot time, via the
-       # sdbootutil-update-predictions service
+       # sdbootutil-update-predictions service.
+       #
+       # As systemd-pcrlock does not drop a PCR that exceed the
+       # PolicyPR limit, we need to first create a prediction and
+       # count the values
        local limit=1
        is_transactional || limit=3
 
-       # If the system is transactional, drop the shift variation.
-       # If there is a new kernel, only the newest one will be
-       # measured (sort_by) and the current one that is in the event
-       # log will not be present in any variation.  This will make
-       # pcrlock lost the track and drop the component.  But if there
-       # is not new kernel or initrd, then the only variation will be
-       # found in the event log
-
        # Join the kernel and the initrd in a single component
-       is_transactional || shift_component 710-grub2-bls-kernel-initrd-entry
+       shift_component 710-grub2-bls-kernel-initrd-entry
        n=0
        while read -r linux; do
                read -r initrd
@@ -2728,6 +2920,58 @@
        fi
 }
 
+get_final_pcrs()
+{
+       local pcrs="$1"
+
+       # Generate a JSON prediction, to get the final PCRs that will
+       # participate in the policy.  To avoid the PolicyOR limit, we
+       # filter the PCRs with more that 8 values
+       local output
+       output="$(pcrlock --pcr="$pcrs" --json=short predict 2>"$tmpfile")"
+       local pcrlock_status=$?
+
+       if [ "$pcrlock_status" -ne 0 ]; then
+               err "Error creating the systemd-pcrlock prediction!\n$(cat 
"$tmpfile")"
+       fi
+
+       # If no PCRs are included, we are starting from a very
+       # misaligned event log (initial installation, for example)
+       [ ! "$output" = "{}" ] || {
+               echo "$pcrs"
+               return 0
+       }
+
+       # PCRs that participate in the policy
+       local pcrs_policy
+       pcrs_policy="$(jq -r '[.sha256[] | select(.values | length <= 8) | 
.pcr] | join(",")' <<<"$output")"
+
+       # PCRs dropped because they have more than 8 values
+       local pcrs_policyor
+       pcrs_policyor="$(jq -r '[.sha256[] | select(.values | length > 8) | 
.pcr] | join(",")' <<<"$output")"
+
+       local i
+       local -A pcrs_policy_table
+       while read -r -d ',' i; do
+               pcrs_policy_table[$i]=1
+       done <<<"$pcrs_policy"
+
+       local -A pcrs_policy_missing_table
+       while read -r -d ',' i; do
+               if [ -z "${pcrs_policy_table[$i]}" ]; then
+                       pcrs_policy_missing_table[$i]=1
+               fi
+       done <<<"$pcrs"
+
+       local pcrs_policy_missing
+       pcrs_policy_missing="$(IFS=","; echo 
"${!pcrs_policy_missing_table[*]}")"
+       [ -z "$pcrs_policy_missing" ] || info "PCRs $pcrs_policy_missing 
dropped from the policy (component mapping)"
+       [ -z "$pcrs_policyor" ] || info "PCRs $pcrs_policyor dropped from the 
policy (PolicyOR)"
+       [ "$pcrs" = "$pcrs_policy" ] || info "Final PCRs list ($pcrs -> 
$pcrs_policy)"
+
+       echo "$pcrs_policy"
+}
+
 generate_tpm2_predictions_pcrlock()
 {
        local pcrs="$FDE_SEAL_PCR_LIST"
@@ -2852,12 +3096,15 @@
                extra=("--recovery-pin=show")
        fi
 
+       local final_pcrs
+       final_pcrs="$(get_final_pcrs "$pcrs")"
+
        local output
-       output="$(PIN="$pin" pcrlock --pcr="$pcrs" "${extra[@]}" make-policy)"
+       output="$(PIN="$pin" pcrlock --pcr="$final_pcrs" "${extra[@]}" 
make-policy 2>"$tmpfile")"
        local pcrlock_status=$?
 
-       if [ $pcrlock_status -ne 0 ]; then
-               echo "Error creating the systemd-pcrlock policy!"
+       if [ "$pcrlock_status" -ne 0 ]; then
+               warn "Error creating the systemd-pcrlock policy!\n$(cat 
"$tmpfile")"
                return 1
        elif echo "$output" | grep -q "recovery PIN"; then
                local split
@@ -3139,13 +3386,11 @@
        # situation but fail during the initial enrollment.  This is
        # because we generate the prediction first and later we do the
        # enrollment
-       is_config_file || {
-               warn "/etc/sysconfig/fde-tools not found (manual enrollment?)"
+       [ -n "$FDE_SEAL_PCR_LIST" ] || {
+               warn "FDE_SEAL_PCR_LIST no found in /etc/default/sdbootutil 
(manual enrollment?)"
                warn "No TPM2 predictions generated"
                return 0
        }
-       load_config_file
-       [ -z "$arg_pcr" ] || FDE_SEAL_PCR_LIST="$arg_pcr"
 
        if is_pcr_oracle; then
                generate_tpm2_predictions_pcr_oracle
@@ -3654,27 +3899,6 @@
        # early.  Also we need to set the PCRs used to assest the
        # system status
        if [ "$arg_method" = "tpm2" ] || [ "$arg_method" = "tpm2+pin" ]; then
-               load_config_file
-               [ -z "$arg_pcr" ] || FDE_SEAL_PCR_LIST="$arg_pcr"
-
-               if [ -z "${FDE_SEAL_PCR_LIST}" ]; then
-                       if systemd-detect-virt -q; then
-                               info "Virtualized systemd detected 
($(systemd-detect-virt)). Dropping PCR0 and PCR2"
-                               FDE_SEAL_PCR_LIST=""
-                       else
-                               FDE_SEAL_PCR_LIST="0,2,"
-                       fi
-                       if is_sdboot; then
-                               FDE_SEAL_PCR_LIST+="4,7,9"
-                       elif is_grub2_bls; then
-                               FDE_SEAL_PCR_LIST+="4,7,8,9"
-                       else
-                               err "Bootloader not detected"
-                       fi
-               fi
-
-               is_config_file || echo "FDE_SEAL_PCR_LIST=${FDE_SEAL_PCR_LIST}" 
>> /etc/default/fde-tools
-
                if { ! have_pcrlock || [ -n "$arg_signed_policy" ]; } && 
have_pcr_oracle; then
                        # Once the RSA key is present, then
                        # is_pcr_oracle is true
@@ -3954,6 +4178,8 @@
                [measure-pcr]=""
                [pcr]="_none"
                [devices]="_devices"
+               [rootfs]="_rootfs"
+               [rootfs-data]="_rootfs_data"
                [force]=""
        )
        opts_long=""
@@ -4009,6 +4235,8 @@
                --measure-pcr) arg_measure_pcr=1; shift ;;
                --pcr) arg_pcr="$2"; shift 2 ;;
                --devices) IFS=',' read -r -a tracked_devices <<<"$2"; shift 2 
;;
+               --rootfs) arg_rootfs="$2"; shift 2 ;;
+               --rootfs-data) arg_rootfs_data="$2"; shift 2 ;;
                --force) arg_force=1; shift ;;
                --) shift ; break ;;
                *) echo "Internal error!" ; exit 1 ;;
@@ -4034,9 +4262,7 @@
 [ -n "$arg_esp_path" ] && export SYSTEMD_ESP_PATH="$arg_esp_path"
 
 eval_bootctl
-read -r root_uuid root_device < <(findmnt / -v -r -n -o UUID,SOURCE)
-root_device_is_crypt=
-[ "$(lsblk --noheadings -o TYPE "$root_device")" = "crypt" ] && 
root_device_is_crypt=1
+
 root_subvol=""
 subvol_prefix=""
 if [ "$(stat -f -c %T /)" = "btrfs" ] && [ -d /.snapshots ]; then
@@ -4061,13 +4287,11 @@
 [ -n "$arg_arch" ] && firmware_arch="$arg_arch"
 
 [ -n "$boot_root" ] || err "No ESP detected. Legacy system?"
-[ -n "$root_uuid" ] || err "Can't determine root UUID"
 [ -n "$root_subvol" ] || [ -z "$have_snapshots" ] || err "Can't determine root 
subvolume"
-[ -n "$root_device" ] || err "Can't determine root device"
 [ -n "$firmware_arch" ] || err "Can't determine firmware arch"
 set_image_name
 
-mountpoint -q "$boot_root" || err "$boot_root is not a valid mountpoint"
+mountpoint -q "$boot_root" || warn "$boot_root is not a valid mountpoint"
 
 dbg_var "root_snapshot"
 dbg_var "boot_root"
@@ -4116,6 +4340,17 @@
        arg_no_variables=1
 fi
 
+# If there is a config file, load it.  If not, but the bootloader was
+# installed, create a default one (using the CLI arguments).  If not,
+# use some default values.
+if is_config_file; then
+       load_config_file
+elif is_installed; then
+       create_default_config_file
+else
+       set_default_config_values
+fi
+
 # Keep initial components before they are replaced by some actions
 # (new initrd, new entry, etc)
 if [ "$SDB_ADD_INITIAL_COMPONENT" = "1" ]; then
@@ -4124,7 +4359,8 @@
 
 case "$1" in
        install)
-               install_bootloader "${2:-$root_snapshot}" ;;
+               install_bootloader "${2:-$root_snapshot}"
+               create_default_config_file ;;
        needs-update)
                bootloader_needs_update "${2:-$root_snapshot}" ;;
        update)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/sdbootutil-1+git20260210.81c4815/sdbootutil-update-predictions.service 
new/sdbootutil-1+git20260303.90d816d/sdbootutil-update-predictions.service
--- old/sdbootutil-1+git20260210.81c4815/sdbootutil-update-predictions.service  
2026-02-10 13:47:27.000000000 +0100
+++ new/sdbootutil-1+git20260303.90d816d/sdbootutil-update-predictions.service  
2026-03-03 11:19:37.000000000 +0100
@@ -6,16 +6,16 @@
 Type=oneshot
 RemainAfterExit=yes
 KeyringMode=shared
-PrivateTmp=no
-ExecStartPre=/usr/bin/sh -c 'cp -a /var/lib/pcrlock.d /tmp/pcrlock.d.bak'
+PrivateTmp=yes
+ExecStartPre=/usr/bin/sh -c 'mkdir "/tmp/$INVOCATION_ID"; cp -a 
/var/lib/pcrlock.d /tmp/$INVOCATION_ID/pcrlock.d'
 ExecStart=/usr/bin/sdbootutil -v update-predictions
 ExecStopPost=/usr/bin/sh -c '\
-    if [ "$EXIT_STATUS" != "0" ]; then \
-        echo "Command failed (Status: $EXIT_STATUS). Restoring backup..."; \
+    if [ "$SERVICE_RESULT" != "success" ]; then \
+        echo "Command failed. Reason: $SERVICE_RESULT (Status: $EXIT_STATUS). 
Restoring backup..."; \
         rm -rf /var/lib/pcrlock.d/*; \
-        cp -a /tmp/pcrlock.d.bak/. /var/lib/pcrlock.d/; \
+        cp -a "/tmp/$INVOCATION_ID/pcrlock.d/." /var/lib/pcrlock.d/; \
     fi; \
-    rm -rf /tmp/pcrlock.d.bak'
+    rm -rf "/tmp/$INVOCATION_ID/pcrlock.d"'
 ImportCredential=sdbootutil-update-predictions.*
 
 [Install]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sdbootutil-1+git20260210.81c4815/sdbootutil.spec 
new/sdbootutil-1+git20260303.90d816d/sdbootutil.spec
--- old/sdbootutil-1+git20260210.81c4815/sdbootutil.spec        2026-02-10 
13:47:27.000000000 +0100
+++ new/sdbootutil-1+git20260303.90d816d/sdbootutil.spec        2026-03-03 
11:19:37.000000000 +0100
@@ -31,7 +31,6 @@
 BuildRequires:  libopenssl-devel
 BuildRequires:  systemd-rpm-macros
 Requires:       %{name}-dracut-measure-pcr
-Requires:       dialog
 Requires:       dracut-pcr-signature
 Requires:       efibootmgr
 Requires:       jq

++++++ sdbootutil.obsinfo ++++++
--- /var/tmp/diff_new_pack.8LiqUZ/_old  2026-03-04 20:59:42.842791774 +0100
+++ /var/tmp/diff_new_pack.8LiqUZ/_new  2026-03-04 20:59:42.850792103 +0100
@@ -1,5 +1,5 @@
 name: sdbootutil
-version: 1+git20260210.81c4815
-mtime: 1770727647
-commit: 81c48154d681e5d93625629081fe66aa838e8095
+version: 1+git20260303.90d816d
+mtime: 1772533177
+commit: 90d816d884019f7ffa0dc7b8e1dc866bfe7f922a
 

Reply via email to