util/grub.d/30_os-prober.in: Fix GRUB_OS_PROBER_SKIP_LIST for non-EFI

GRUB documentation states:

  GRUB_OS_PROBER_SKIP_LIST
    List of space-separated FS UUIDs of filesystems to be ignored from
    os-prober output. For efi chainloaders it’s <UUID>@<EFI FILE>

But the actual behaviour does not match this description.

  GRUB_OS_PROBER_SKIP_LIST="<UUID>"

does nothing. In order to skip non-EFI bootloaders, you must set

  GRUB_OS_PROBER_SKIP_LIST="<UUID>@<DEVICE>"

which is both absurd, <UUID> and <DEVICE> are redundant, and wrong,
<DEVICE> such as /dev/sd* may not be persistent across boots.

Also, any non-word character is accepted as a separator, including "-"
and "@" which may be present in UUIDs. This can cause false positives
because of partial UUID match.

This patch fixes these flaws while retaining some backward compatibility
with previous behaviour which may be expected by existing setups:
  - also accept <UUID>@/dev/* (with warning) for non-EFI bootloaders,
  - also accept comma and semicolon as separator.

Fixes: 55e706c9 (Add GRUB_OS_PROBER_SKIP_LIST to selectively skipping systems)

Signed-off-by: Pascal Hambourg <pascal@plouf.fr.eu.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
Pascal Hambourg 2025-02-21 12:20:28 +01:00 committed by Daniel Kiper
parent 01f064064c
commit 56ccc5ed56
2 changed files with 18 additions and 8 deletions

View File

@ -1562,8 +1562,11 @@ this option to @samp{false} to enable this feature in the
@command{grub-mkconfig} command. @command{grub-mkconfig} command.
@item GRUB_OS_PROBER_SKIP_LIST @item GRUB_OS_PROBER_SKIP_LIST
List of space-separated FS UUIDs of filesystems to be ignored from os-prober List of space-separated case insensitive UUIDs of filesystems to be ignored
output. For efi chainloaders it's <UUID>@@<EFI FILE> from os-prober output. For EFI chainloaders it's <UUID>@@<EFI FILE>. For
backward compatibility with previous behaviour, <UUID>@@/dev/* is also accepted
for non-EFI chainloaders even if the device does not match, and comma and
semicolon are also accepted as separator.
@item GRUB_DISABLE_SUBMENU @item GRUB_DISABLE_SUBMENU
Normally, @command{grub-mkconfig} will generate top level menu entry for Normally, @command{grub-mkconfig} will generate top level menu entry for

View File

@ -117,19 +117,26 @@ if [ "x$GRUB_TOP_LEVEL_OS_PROBER" != x ]; then
OSPROBED=$(grub_move_to_front "$GRUB_TOP_LEVEL_OS_PROBER" ${OSPROBED}) OSPROBED=$(grub_move_to_front "$GRUB_TOP_LEVEL_OS_PROBER" ${OSPROBED})
fi fi
case "$GRUB_OS_PROBER_SKIP_LIST" in *@/[dD][eE][vV]/*)
grub_warn "$(gettext_printf "GRUB_OS_PROBER_SKIP_LIST contains deprecated <UUID>@/dev/* notation. The @/dev/* suffix is ignored.")"
esac
for OS in ${OSPROBED} ; do for OS in ${OSPROBED} ; do
DEVICE="`echo ${OS} | cut -d ':' -f 1`" DEVICE="`echo ${OS} | cut -d ':' -f 1`"
LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`" LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`"
LABEL="`echo ${OS} | cut -d ':' -f 3 | tr '^' ' '`" LABEL="`echo ${OS} | cut -d ':' -f 3 | tr '^' ' '`"
BOOT="`echo ${OS} | cut -d ':' -f 4`" BOOT="`echo ${OS} | cut -d ':' -f 4`"
if UUID="`${grub_probe} --target=fs_uuid --device ${DEVICE%@*}`"; then unset UUID
EXPUUID="$UUID" if [ -n "${GRUB_OS_PROBER_SKIP_LIST}" ] && UUID="`${grub_probe} --target=fs_uuid --device ${DEVICE%@*}`"; then
SPACE='[[:space:],;]' # regex matching spaces and common separators
if [ x"${DEVICE#*@}" != x ] ; then if [ x"${DEVICE##*@*}" = x ] ; then
EXPUUID="${EXPUUID}@${DEVICE#*@}" EXPUUID="$UUID@${DEVICE#*@}"
else
EXPUUID="$UUID(@/dev/.*)?"
fi fi
if [ "x${GRUB_OS_PROBER_SKIP_LIST}" != "x" ] && [ "x`echo ${GRUB_OS_PROBER_SKIP_LIST} | grep -i -e '\b'${EXPUUID}'\b'`" != "x" ] ; then if printf %s " ${GRUB_OS_PROBER_SKIP_LIST} " | grep -Eqie "${SPACE}${EXPUUID}${SPACE}" ; then
echo "Skipped ${LONGNAME} on ${DEVICE} by user request." >&2 echo "Skipped ${LONGNAME} on ${DEVICE} by user request." >&2
continue continue
fi fi
@ -299,7 +306,7 @@ EOF
echo "$title_correction_code" echo "$title_correction_code"
;; ;;
macosx) macosx)
if [ "${UUID}" ]; then if [ "${UUID=`${grub_probe} --target=fs_uuid --device ${DEVICE}`}" ]; then
OSXUUID="${UUID}" OSXUUID="${UUID}"
osx_entry xnu_kernel 32 osx_entry xnu_kernel 32
osx_entry xnu_kernel64 64 osx_entry xnu_kernel64 64