From 8d295b5bc55d0fa87ea08911d97e99ff2c125a1d Mon Sep 17 00:00:00 2001 From: Qiumiao Zhang Date: Mon, 11 Mar 2024 08:45:49 +0000 Subject: [PATCH] Don't require a password to boot entries generated by grub-mkconfig Signed-off-by: Qiumiao Zhang (cherry picked from commit e07518a0fb083b68bc4dbf4ea3b2eb6bcbe7c5f6) --- ...n-t-say-GNU-Linux-in-generated-menus.patch | 39 +++ ...password-to-boot-entries-generated-b.patch | 28 ++ ...-before-grub.cfg-on-tftp-config-file.patch | 127 +++++++ ...CLASS-in-10_linux-from-etc-os-releas.patch | 29 ++ 0032-Try-prefix-if-fw_path-doesn-t-work.patch | 222 +++++++++++++ ...fig-construct-titles-that-look-like-.patch | 73 ++++ ...ly-grub2-password-config-tool-985962.patch | 246 ++++++++++++++ grub.patches | 10 +- ...rd-prompts-to-enter-the-current-pass.patch | 313 ++++++++++++++++++ grub2.spec | 8 +- 10 files changed, 1093 insertions(+), 2 deletions(-) create mode 100644 0024-Don-t-say-GNU-Linux-in-generated-menus.patch create mode 100644 0026-Don-t-require-a-password-to-boot-entries-generated-b.patch create mode 100644 0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch create mode 100644 0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch create mode 100644 0032-Try-prefix-if-fw_path-doesn-t-work.patch create mode 100644 0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch create mode 100644 0035-Add-friendly-grub2-password-config-tool-985962.patch create mode 100644 grub2-set-password-prompts-to-enter-the-current-pass.patch diff --git a/0024-Don-t-say-GNU-Linux-in-generated-menus.patch b/0024-Don-t-say-GNU-Linux-in-generated-menus.patch new file mode 100644 index 0000000..c55801f --- /dev/null +++ b/0024-Don-t-say-GNU-Linux-in-generated-menus.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 14 Mar 2011 14:27:42 -0400 +Subject: [PATCH] Don't say "GNU/Linux" in generated menus. + +--- + util/grub.d/10_linux.in | 2 +- + util/grub.d/20_linux_xen.in | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index ae487a7..7b51a38 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -29,7 +29,7 @@ export TEXTDOMAINDIR="@localedir@" + CLASS="--class gnu-linux --class gnu --class os" + + if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then +- OS=GNU/Linux ++ OS="$(sed 's, release .*$,,g' /etc/system-release)" + else + OS="${GRUB_DISTRIBUTOR}" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" +diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in +index 4cc03a7..87ecb1e 100644 +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -37,7 +37,7 @@ fi + CLASS="--class gnu-linux --class gnu --class os --class xen" + + if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then +- OS=GNU/Linux ++ OS="$(sed 's, release .*$,,g' /etc/system-release)" + os=linux + else + OS="${GRUB_DISTRIBUTOR}" +-- +2.33.0 + diff --git a/0026-Don-t-require-a-password-to-boot-entries-generated-b.patch b/0026-Don-t-require-a-password-to-boot-entries-generated-b.patch new file mode 100644 index 0000000..ac9475e --- /dev/null +++ b/0026-Don-t-require-a-password-to-boot-entries-generated-b.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 11 Feb 2014 11:14:50 -0500 +Subject: [PATCH] Don't require a password to boot entries generated by + grub-mkconfig. + +When we set a password, we just want that to mean you can't /edit/ an entry. + +Resolves: rhbz#1030176 + +Signed-off-by: Peter Jones +--- + util/grub.d/10_linux.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index 4a499c53a61..cf8d1186981 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -26,7 +26,7 @@ datarootdir="@datarootdir@" + export TEXTDOMAIN=@PACKAGE@ + export TEXTDOMAINDIR="@localedir@" + +-CLASS="--class gnu-linux --class gnu --class os" ++CLASS="--class gnu-linux --class gnu --class os --unrestricted" + + if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then + OS="$(sed 's, release .*$,,g' /etc/system-release)" diff --git a/0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch b/0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch new file mode 100644 index 0000000..ab49bb1 --- /dev/null +++ b/0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch @@ -0,0 +1,127 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 8 Jul 2019 17:33:22 +0200 +Subject: [PATCH] Try mac/guid/etc before grub.cfg on tftp config files. + +Signed-off-by: Peter Jones +--- + grub-core/normal/main.c | 97 ++++++++++++++++++++++++++----------------------- + 1 file changed, 51 insertions(+), 46 deletions(-) + +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 02577502116..880d0ebd454 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -345,61 +345,66 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), + /* Guess the config filename. It is necessary to make CONFIG static, + so that it won't get broken by longjmp. */ + char *config; +- const char *prefix, *fw_path; +- +- prefix = fw_path = grub_env_get ("fw_path"); +- if (fw_path) +- { +- config = grub_xasprintf ("%s/grub.cfg", fw_path); +- if (config) +- { +- grub_file_t file; +- +- file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); +- if (file) +- { +- grub_file_close (file); +- grub_enter_normal_mode (config); +- } +- else +- { +- /* Ignore all errors. */ +- grub_errno = 0; +- } +- grub_free (config); +- } +- } ++ const char *prefix; ++ const char *net_search_cfg; ++ int disable_net_search = 0; + ++ prefix = grub_env_get ("fw_path"); + if (! prefix) + prefix = grub_env_get ("prefix"); ++ ++ net_search_cfg = grub_env_get ("feature_net_search_cfg"); ++ if (net_search_cfg && net_search_cfg[0] == 'n') ++ disable_net_search = 1; ++ + if (prefix) + { +- grub_size_t config_len; +- int disable_net_search = 0; +- const char *net_search_cfg; +- +- config_len = grub_strlen (prefix) + +- sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); +- config = grub_malloc (config_len); +- +- if (!config) +- goto quit; +- +- grub_snprintf (config, config_len, "%s/grub.cfg", prefix); +- +- net_search_cfg = grub_env_get ("feature_net_search_cfg"); +- if (net_search_cfg && net_search_cfg[0] == 'n') +- disable_net_search = 1; +- + if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && + !disable_net_search) +- grub_net_search_config_file (config); ++ { ++ grub_size_t config_len; ++ config_len = grub_strlen (prefix) + ++ sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); ++ config = grub_malloc (config_len); + +- grub_enter_normal_mode (config); +- grub_free (config); +- } ++ if (! config) ++ goto quit; ++ ++ grub_snprintf (config, config_len, "%s/grub.cfg", prefix); ++ ++ grub_net_search_configfile (config); ++ ++ grub_enter_normal_mode (config); ++ grub_free (config); ++ config = NULL; ++ } ++ ++ if (!config) ++ { ++ config = grub_xasprintf ("%s/grub.cfg", prefix); ++ if (config) ++ { ++ grub_file_t file; ++ ++ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); ++ if (file) ++ { ++ grub_file_close (file); ++ grub_enter_normal_mode (config); ++ } ++ else ++ { ++ /* Ignore all errors. */ ++ grub_errno = 0; ++ } ++ grub_free (config); ++ } ++ } ++ } + else +- grub_enter_normal_mode (0); ++ { ++ grub_enter_normal_mode (0); ++ } + } + else + grub_enter_normal_mode (argv[0]); diff --git a/0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch b/0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch new file mode 100644 index 0000000..245faf7 --- /dev/null +++ b/0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Thu, 4 Sep 2014 14:23:23 -0400 +Subject: [PATCH] Generate OS and CLASS in 10_linux from /etc/os-release + +This makes us use pretty names in the titles we generate in +grub2-mkconfig when GRUB_DISTRIBUTOR isn't set. + +Resolves: rhbz#996794 + +Signed-off-by: Peter Jones +--- + util/grub.d/10_linux.in | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index cf8d1186981..5f6d3c8d52d 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -29,7 +29,8 @@ export TEXTDOMAINDIR="@localedir@" + CLASS="--class gnu-linux --class gnu --class os --unrestricted" + + if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then +- OS="$(sed 's, release .*$,,g' /etc/system-release)" ++ OS="$(eval $(grep PRETTY_NAME /etc/os-release) ; echo ${PRETTY_NAME})" ++ CLASS="--class $(eval $(grep '^ID_LIKE=\|^ID=' /etc/os-release) ; [ -n "${ID_LIKE}" ] && echo ${ID_LIKE} || echo ${ID}) ${CLASS}" + else + OS="${GRUB_DISTRIBUTOR}" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" diff --git a/0032-Try-prefix-if-fw_path-doesn-t-work.patch b/0032-Try-prefix-if-fw_path-doesn-t-work.patch new file mode 100644 index 0000000..54a876b --- /dev/null +++ b/0032-Try-prefix-if-fw_path-doesn-t-work.patch @@ -0,0 +1,222 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 9 Jul 2019 10:35:16 +0200 +Subject: [PATCH] Try $prefix if $fw_path doesn't work. + +Related: rhbz#1148652 + +Signed-off-by: Peter Jones +--- + grub-core/kern/ieee1275/init.c | 28 +++++---- + grub-core/net/net.c | 2 +- + grub-core/normal/main.c | 134 ++++++++++++++++++++--------------------- + 3 files changed, 82 insertions(+), 82 deletions(-) + +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c +index e71d1584164..0cd2a627231 100644 +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -127,23 +127,25 @@ grub_machine_get_bootlocation (char **device, char **path) + grub_free (canon); + } + else +- *device = grub_ieee1275_encode_devname (bootpath); +- grub_free (type); +- +- filename = grub_ieee1275_get_filename (bootpath); +- if (filename) + { +- char *lastslash = grub_strrchr (filename, '\\'); +- +- /* Truncate at last directory. */ +- if (lastslash) ++ filename = grub_ieee1275_get_filename (bootpath); ++ if (filename) + { +- *lastslash = '\0'; +- grub_translate_ieee1275_path (filename); ++ char *lastslash = grub_strrchr (filename, '\\'); + +- *path = filename; +- } ++ /* Truncate at last directory. */ ++ if (lastslash) ++ { ++ *lastslash = '\0'; ++ grub_translate_ieee1275_path (filename); ++ ++ *path = filename; ++ } ++ } ++ *device = grub_ieee1275_encode_devname (bootpath); + } ++ ++ grub_free (type); + grub_free (bootpath); + } + +diff --git a/grub-core/net/net.c b/grub-core/net/net.c +index 4d3eb5c1a52..0ef148f4adc 100644 +--- a/grub-core/net/net.c ++++ b/grub-core/net/net.c +@@ -1869,7 +1869,7 @@ grub_net_search_config_file (char *config) + /* Remove the remaining minus sign at the end. */ + config[config_len] = '\0'; + +- return GRUB_ERR_NONE; ++ return GRUB_ERR_FILE_NOT_FOUND; + } + + static struct grub_preboot *fini_hnd; +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 880d0ebd454..d5df4f815b0 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -335,81 +335,79 @@ grub_enter_normal_mode (const char *config) + grub_boot_time ("Exiting normal mode"); + } + ++static grub_err_t ++grub_try_normal (const char *variable) ++{ ++ char *config; ++ const char *prefix; ++ grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; ++ const char *net_search_cfg; ++ int disable_net_search = 0; ++ ++ prefix = grub_env_get (variable); ++ if (!prefix) ++ return GRUB_ERR_FILE_NOT_FOUND; ++ ++ net_search_cfg = grub_env_get ("feature_net_search_cfg"); ++ if (net_search_cfg && net_search_cfg[0] == 'n') ++ disable_net_search = 1; ++ ++ if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && ++ !disable_net_search) ++ { ++ grub_size_t config_len; ++ config_len = grub_strlen (prefix) + ++ sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); ++ config = grub_malloc (config_len); ++ ++ if (! config) ++ return GRUB_ERR_FILE_NOT_FOUND; ++ ++ grub_snprintf (config, config_len, "%s/grub.cfg", prefix); ++ err = grub_net_search_config_file (config); ++ } ++ ++ if (err != GRUB_ERR_NONE) ++ { ++ config = grub_xasprintf ("%s/grub.cfg", prefix); ++ if (config) ++ { ++ grub_file_t file; ++ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); ++ if (file) ++ { ++ grub_file_close (file); ++ err = GRUB_ERR_NONE; ++ } ++ } ++ } ++ ++ if (err == GRUB_ERR_NONE) ++ grub_enter_normal_mode (config); ++ ++ grub_errno = 0; ++ grub_free (config); ++ return err; ++} ++ + /* Enter normal mode from rescue mode. */ + static grub_err_t + grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) + { +- if (argc == 0) +- { +- /* Guess the config filename. It is necessary to make CONFIG static, +- so that it won't get broken by longjmp. */ +- char *config; +- const char *prefix; +- const char *net_search_cfg; +- int disable_net_search = 0; +- +- prefix = grub_env_get ("fw_path"); +- if (! prefix) +- prefix = grub_env_get ("prefix"); +- +- net_search_cfg = grub_env_get ("feature_net_search_cfg"); +- if (net_search_cfg && net_search_cfg[0] == 'n') +- disable_net_search = 1; +- +- if (prefix) +- { +- if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && +- !disable_net_search) +- { +- grub_size_t config_len; +- config_len = grub_strlen (prefix) + +- sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); +- config = grub_malloc (config_len); +- +- if (! config) +- goto quit; +- +- grub_snprintf (config, config_len, "%s/grub.cfg", prefix); +- +- grub_net_search_configfile (config); +- +- grub_enter_normal_mode (config); +- grub_free (config); +- config = NULL; +- } +- +- if (!config) +- { +- config = grub_xasprintf ("%s/grub.cfg", prefix); +- if (config) +- { +- grub_file_t file; +- +- file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); +- if (file) +- { +- grub_file_close (file); +- grub_enter_normal_mode (config); +- } +- else +- { +- /* Ignore all errors. */ +- grub_errno = 0; +- } +- grub_free (config); +- } +- } +- } +- else +- { +- grub_enter_normal_mode (0); +- } +- } +- else ++ if (argc) + grub_enter_normal_mode (argv[0]); ++ else ++ { ++ /* Guess the config filename. */ ++ grub_err_t err; ++ err = grub_try_normal ("fw_path"); ++ if (err == GRUB_ERR_FILE_NOT_FOUND) ++ err = grub_try_normal ("prefix"); ++ if (err == GRUB_ERR_FILE_NOT_FOUND) ++ grub_enter_normal_mode (0); ++ } + +-quit: + return 0; + } + diff --git a/0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch b/0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch new file mode 100644 index 0000000..9a5235d --- /dev/null +++ b/0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch @@ -0,0 +1,73 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Tue, 28 Apr 2015 11:15:03 -0400 +Subject: [PATCH] Make grub2-mkconfig construct titles that look like the ones + we want elsewhere. + +Resolves: rhbz#1215839 + +Signed-off-by: Peter Jones + +--- + util/grub.d/10_linux.in | 34 +++++++++++++++++++++++++++------- + 1 file changed, 27 insertions(+), 7 deletions(-) + +diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in +index 6e5e3d7..1a4c846 100644 +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -88,6 +88,32 @@ case x"$GRUB_FS" in + ;; + esac + ++mktitle () ++{ ++ local title_type ++ local version ++ local OS_NAME ++ local OS_VERS ++ ++ title_type=$1 && shift ++ version=$1 && shift ++ ++ OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})" ++ OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})" ++ ++ case $title_type in ++ recovery) ++ title=$(printf '%s (%s) %s (recovery mode)' \ ++ "${OS_NAME}" "${version}" "${OS_VERS}") ++ ;; ++ *) ++ title=$(printf '%s (%s) %s' \ ++ "${OS_NAME}" "${version}" "${OS_VERS}") ++ ;; ++ esac ++ echo -n ${title} ++} ++ + if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then + LINUX_ROOT_DEVICE="" + fi +@@ -126,17 +152,11 @@ linux_entry () + boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" + fi + if [ x$type != xsimple ] ; then +- case $type in +- recovery) +- title="$(gettext_printf "%s, with Linux %s (recovery mode)" "${os}" "${version}")" ;; +- *) +- title="$(gettext_printf "%s, with Linux %s" "${os}" "${version}")" ;; +- esac ++ title=$(mktitle "$type" "$version") + if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then + replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')" + quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)" + title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;" +- grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")" + fi + echo "menuentry '$(echo "$title" | grub_quote)' $(print_hotkey) ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/" + hotkey=$(incr_hotkey) +-- +2.33.0 + diff --git a/0035-Add-friendly-grub2-password-config-tool-985962.patch b/0035-Add-friendly-grub2-password-config-tool-985962.patch new file mode 100644 index 0000000..9d1c858 --- /dev/null +++ b/0035-Add-friendly-grub2-password-config-tool-985962.patch @@ -0,0 +1,246 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Robert Marshall +Date: Thu, 25 Jun 2015 11:13:11 -0400 +Subject: [PATCH] Add friendly grub2 password config tool (#985962) + +Provided a tool for users to reset the grub2 root user password +without having to alter the grub.cfg. The hashed password now +lives in a root-only-readable configuration file. + +Resolves: rhbz#985962 + +Signed-off-by: Robert Marshall +[pjones: fix the efidir in grub-setpassword and rename tool] +Signed-off-by: Peter Jones +[luto: fix grub-setpassword -o's output path] +Andy Lutomirski +--- + Makefile.util.def | 13 ++++ + configure.ac | 1 + + docs/man/grub-set-password.h2m | 2 + + util/grub-mkconfig.in | 2 + + util/grub-set-password.in | 128 +++++++++++++++++++++++++++++++++ + util/grub.d/01_users.in | 11 +++ + 6 files changed, 157 insertions(+) + create mode 100644 docs/man/grub-set-password.h2m + create mode 100644 util/grub-set-password.in + create mode 100644 util/grub.d/01_users.in + +diff --git a/Makefile.util.def b/Makefile.util.def +index b384e16..b916c19 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -465,6 +465,12 @@ script = { + installdir = grubconf; + }; + ++script = { ++ name = '01_users'; ++ common = util/grub.d/01_users.in; ++ installdir = grubconf; ++}; ++ + script = { + name = '05_crypttab'; + common = util/grub.d/05_crypttab.in; +@@ -763,6 +769,13 @@ script = { + installdir = sbin; + }; + ++script = { ++ name = grub-set-password; ++ common = util/grub-set-password.in; ++ mansection = 8; ++ installdir = sbin; ++}; ++ + script = { + name = grub-zipl-setup; + installdir = sbin; +diff --git a/configure.ac b/configure.ac +index 942db8f..8878e91 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -78,6 +78,7 @@ grub_TRANSFORM([grub-mkrescue]) + grub_TRANSFORM([grub-probe]) + grub_TRANSFORM([grub-protect]) + grub_TRANSFORM([grub-reboot]) ++grub_TRANSFORM([grub-set-password]) + grub_TRANSFORM([grub-script-check]) + grub_TRANSFORM([grub-set-default]) + grub_TRANSFORM([grub-sparc64-setup]) +diff --git a/docs/man/grub-set-password.h2m b/docs/man/grub-set-password.h2m +new file mode 100644 +index 0000000..10ee82f +--- /dev/null ++++ b/docs/man/grub-set-password.h2m +@@ -0,0 +1,2 @@ ++[NAME] ++grub-set-password \- generate the user.cfg file containing the hashed grub bootloader password +diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in +index 4b3510a..f8ec65b 100644 +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -332,6 +332,8 @@ for i in "${grub_mkconfig_dir}"/* ; do + *~) ;; + # emacsen autosave files. FIXME: support other editors + */\#*\#) ;; ++ # rpm config files of yore. ++ *.rpmsave|*.rpmnew|*.rpmorig) ;; + *) + if grub_file_is_not_garbage "$i" && test -x "$i" ; then + echo +diff --git a/util/grub-set-password.in b/util/grub-set-password.in +new file mode 100644 +index 0000000..c0b5ebb +--- /dev/null ++++ b/util/grub-set-password.in +@@ -0,0 +1,128 @@ ++#!/bin/sh -e ++ ++EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g') ++if [ -d /sys/firmware/efi/efivars/ ]; then ++ grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` ++else ++ grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` ++fi ++ ++PACKAGE_VERSION="@PACKAGE_VERSION@" ++PACKAGE_NAME="@PACKAGE_NAME@" ++self=`basename $0` ++bindir="@bindir@" ++grub_mkpasswd="${bindir}/@grub_mkpasswd_pbkdf2@" ++ ++# Usage: usage ++# Print the usage. ++usage () { ++ cat < put user.cfg in a user-selected directory ++ ++Report bugs at https://bugzilla.redhat.com. ++EOF ++} ++ ++argument () { ++ opt=$1 ++ shift ++ ++ if test $# -eq 0; then ++ gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2 ++ exit 1 ++ fi ++ echo $1 ++} ++ ++# Ensure that it's the root user running this script ++if [ "${EUID}" -ne 0 ]; then ++ echo "The grub bootloader password may only be set by root." ++ usage ++ exit 2 ++fi ++ ++# Check the arguments. ++while test $# -gt 0 ++do ++ option=$1 ++ shift ++ ++ case "$option" in ++ -h | --help) ++ usage ++ exit 0 ;; ++ -v | --version) ++ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" ++ exit 0 ;; ++ -o | --output) ++ OUTPUT_PATH=`argument $option "$@"`; shift ;; ++ --output=*) ++ OUTPUT_PATH=`echo "$option" | sed 's/--output=//'` ;; ++ -o=*) ++ OUTPUT_PATH=`echo "$option" | sed 's/-o=//'` ;; ++ esac ++done ++ ++# set user input or default path for user.cfg file ++if [ -z "${OUTPUT_PATH}" ]; then ++ OUTPUT_PATH="${grubdir}" ++fi ++ ++if [ ! -d "${OUTPUT_PATH}" ]; then ++ echo "${OUTPUT_PATH} does not exist." ++ usage ++ exit 2; ++fi ++ ++ttyopt=$(stty -g) ++fixtty() { ++ stty ${ttyopt} ++} ++ ++trap fixtty EXIT ++stty -echo ++ ++# prompt & confirm new grub2 root user password ++echo -n "Enter password: " ++read PASSWORD ++echo ++echo -n "Confirm password: " ++read PASSWORD_CONFIRM ++echo ++stty ${ttyopt} ++ ++getpass() { ++ local P0 ++ local P1 ++ P0="$1" && shift ++ P1="$1" && shift ++ ++ ( echo ${P0} ; echo ${P1} ) | \ ++ LC_ALL=C ${grub_mkpasswd} | \ ++ grep -v '[eE]nter password:' | \ ++ sed -e "s/PBKDF2 hash of your password is //" ++} ++ ++MYPASS="$(getpass "${PASSWORD}" "${PASSWORD_CONFIRM}")" ++if [ -z "${MYPASS}" ]; then ++ echo "${self}: error: empty password" 1>&2 ++ exit 1 ++fi ++ ++# on the ESP, these will fail to set the permissions, but it's okay because ++# the directory is protected. ++install -m 0600 /dev/null "${OUTPUT_PATH}/user.cfg" 2>/dev/null || : ++chmod 0600 "${OUTPUT_PATH}/user.cfg" 2>/dev/null || : ++echo "GRUB2_PASSWORD=${MYPASS}" > "${OUTPUT_PATH}/user.cfg" ++ ++if ! grep -q "^### BEGIN /etc/grub.d/01_users ###$" "${OUTPUT_PATH}/grub.cfg"; then ++ echo "WARNING: The current configuration lacks password support!" ++ echo "Update your configuration with @grub_mkconfig@ to support this feature." ++fi +diff --git a/util/grub.d/01_users.in b/util/grub.d/01_users.in +new file mode 100644 +index 0000000..db2f44b +--- /dev/null ++++ b/util/grub.d/01_users.in +@@ -0,0 +1,11 @@ ++#!/bin/sh -e ++cat << EOF ++if [ -f \${prefix}/user.cfg ]; then ++ source \${prefix}/user.cfg ++ if [ -n "\${GRUB2_PASSWORD}" ]; then ++ set superusers="root" ++ export superusers ++ password_pbkdf2 root \${GRUB2_PASSWORD} ++ fi ++fi ++EOF +-- +2.33.0 + diff --git a/grub.patches b/grub.patches index 176b486..1bf37ec 100644 --- a/grub.patches +++ b/grub.patches @@ -207,6 +207,14 @@ Patch206: remove-the-items-of-unsupported-filesystems-in-fs.ls.patch Patch207: backport-Read-etc-default-grub.d-.cfg-after-etc-default-grub.patch Patch208: modify-klist-in-10_linux.in.patch Patch209: 0019-Add-fw_path-variable-revised.patch -Patch210: 0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch +Patch210: 0024-Don-t-say-GNU-Linux-in-generated-menus.patch +Patch211: 0026-Don-t-require-a-password-to-boot-entries-generated-b.patch +Patch212: 0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch +Patch213: 0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch +Patch214: 0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch +Patch215: 0032-Try-prefix-if-fw_path-doesn-t-work.patch +Patch216: 0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch +Patch217: 0035-Add-friendly-grub2-password-config-tool-985962.patch +Patch218: grub2-set-password-prompts-to-enter-the-current-pass.patch #Patch208: add-TPCM-support-with-ipmi-channel.patch #Patch209: skip-verification-when-not-loading-grub.cfg.patch diff --git a/grub2-set-password-prompts-to-enter-the-current-pass.patch b/grub2-set-password-prompts-to-enter-the-current-pass.patch new file mode 100644 index 0000000..1644e35 --- /dev/null +++ b/grub2-set-password-prompts-to-enter-the-current-pass.patch @@ -0,0 +1,313 @@ +From 23ade142e708ef9c225f0ccfd519e48132793888 Mon Sep 17 00:00:00 2001 +From: liuxin +Date: Thu, 2 Sep 2021 17:30:39 +0800 +Subject: [PATCH] grub2-set-password prompts to enter the current password and + add the password complexity check + +--- + util/grub-mkpasswd-pbkdf2.c | 105 ++++++++++++++++++++++++++++++--- + util/grub-set-password.in | 114 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 212 insertions(+), 7 deletions(-) + +diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c +index 29c68fb..b7c6e48 100644 +--- a/util/grub-mkpasswd-pbkdf2.c ++++ b/util/grub-mkpasswd-pbkdf2.c +@@ -42,10 +42,14 @@ + + #include "progname.h" + ++#define GRUB_PARAM_ERROR 1 ++#define GRUB_PARAM_SUCCESS 0 ++ + static struct argp_option options[] = { + {"iteration-count", 'c', N_("NUM"), 0, N_("Number of PBKDF2 iterations"), 0}, + {"buflen", 'l', N_("NUM"), 0, N_("Length of generated hash"), 0}, + {"salt", 's', N_("NUM"), 0, N_("Length of salt"), 0}, ++ {"salt arg", 'a', N_("VARCHAR"), 0, N_("preset salt var(hex code)"), 0}, + { 0, 0, 0, 0, 0, 0 } + }; + +@@ -54,8 +58,45 @@ struct arguments + unsigned int count; + unsigned int buflen; + unsigned int saltlen; ++ char * salt; + }; + ++static int illegal_char(char t) ++{ ++ int illegal = GRUB_PARAM_ERROR; ++ char legal[] = "0123456789ABCDEF"; ++ for (int i = 0; i < grub_strlen(legal); ++i) { ++ if (t == legal[i]) { ++ illegal = GRUB_PARAM_SUCCESS; ++ break; ++ } ++ } ++ return illegal; ++} ++ ++static int check_salt_verify(const char * arg) ++{ ++ grub_size_t len = grub_strlen(arg); ++ if (len <= 0 || len >= GRUB_SIZE_MAX) ++ { ++ fprintf(stderr, "salt length may be empty or too long!\n"); ++ return GRUB_PARAM_ERROR; ++ } ++ if (len % 2 != 0) ++ { ++ fprintf(stderr, "the salt value length is an even number!\n"); ++ return GRUB_PARAM_ERROR; ++ } ++ for (int i = 0; i < len; ++i) ++ { ++ if (illegal_char(arg[i])) ++ { ++ return GRUB_PARAM_ERROR; ++ } ++ } ++ return GRUB_PARAM_SUCCESS; ++} ++ + static error_t + argp_parser (int key, char *arg, struct argp_state *state) + { +@@ -76,6 +117,16 @@ argp_parser (int key, char *arg, struct argp_state *state) + case 's': + arguments->saltlen = strtoul (arg, NULL, 0); + break; ++ ++ case 'a': ++ if (check_salt_verify(arg)) ++ { ++ fprintf(stderr, "only hexadecimal numbers consisting of digits and uppercase letters are supported\n"); ++ return ARGP_ERR_UNKNOWN; ++ } ++ arguments->saltlen = grub_strlen(arg) / 2; ++ arguments->salt = arg; ++ break; + default: + return ARGP_ERR_UNKNOWN; + } +@@ -110,13 +161,44 @@ hexify (char *hex, grub_uint8_t *bin, grub_size_t n) + *hex = 0; + } + ++static void ++hextobyte(const char *hex, grub_uint8_t *bin, grub_size_t n) ++{ ++ while(n) ++ { ++ grub_uint8_t tmp = 0x00; ++ if (((*hex) <= '9') && ((*hex) >= '0')) ++ { ++ tmp += (grub_uint8_t)((*hex) - '0') << 4 & 0xf0; ++ } ++ else ++ { ++ tmp += (grub_uint8_t)((*hex) - 'A' + 10) << 4 & 0xf0; ++ } ++ hex++; ++ if (((*hex) <= '9') && ((*hex) >= '0')) ++ { ++ tmp += (grub_uint8_t)((*hex) - '0') & 0x0f; ++ } ++ else ++ { ++ tmp += (grub_uint8_t)((*hex) - 'A' + 10) & 0x0f; ++ } ++ *bin = tmp; ++ bin++; ++ hex++; ++ n -= 2; ++ } ++} ++ + int + main (int argc, char *argv[]) + { + struct arguments arguments = { + .count = 10000, + .buflen = 64, +- .saltlen = 64 ++ .saltlen = 64, ++ .salt = NULL + }; + char *result, *ptr; + gcry_err_code_t gcry_err; +@@ -133,6 +215,12 @@ main (int argc, char *argv[]) + exit(1); + } + ++ if (arguments.salt != NULL && grub_strlen(arguments.salt) != 2 * arguments.saltlen) ++ { ++ fprintf(stderr, "%s", _("If the -a parameter is set, don't set the -s parameter again\n")); ++ exit(1); ++ } ++ + buf = xmalloc (arguments.buflen); + salt = xmalloc (arguments.saltlen); + +@@ -161,13 +249,16 @@ main (int argc, char *argv[]) + } + memset (pass2, 0, sizeof (pass2)); + +- if (grub_get_random (salt, arguments.saltlen)) ++ if (arguments.salt != NULL) + { +- memset (pass1, 0, sizeof (pass1)); +- free (buf); +- free (salt); +- grub_util_error ("%s", _("couldn't retrieve random data for salt")); +- } ++ hextobyte(arguments.salt, salt, arguments.saltlen * 2); ++ } else if (grub_get_random (salt, arguments.saltlen)) ++ { ++ memset (pass1, 0, sizeof (pass1)); ++ free (buf); ++ free (salt); ++ grub_util_error ("%s", _("couldn't retrieve random data for salt")); ++ } + + gcry_err = grub_crypto_pbkdf2 (GRUB_MD_SHA512, + (grub_uint8_t *) pass1, strlen (pass1), +diff --git a/util/grub-set-password.in b/util/grub-set-password.in +index c0b5ebb..3e14a5d 100644 +--- a/util/grub-set-password.in ++++ b/util/grub-set-password.in +@@ -87,16 +87,130 @@ fixtty() { + } + + trap fixtty EXIT ++ ++getsaltpass() { ++ local P0 ++ local P1 ++ P0="$1" && shift ++ P1="$1" && shift ++ P2="$1" && shift ++ ++ ( echo ${P0} ; echo ${P1} ) | \ ++ LC_ALL=C ${grub_mkpasswd} -a ${P2} | \ ++ grep -v '[eE]nter password:' | \ ++ sed -e "s/PBKDF2 hash of your password is //" ++} ++ ++verifyusercfgoldpasswd() { ++ # get old password salt ++ expectsalt=`cat ${grubdir}/user.cfg | cut -d "." -f 5` ++ # get expect password ++ expectpass=`cat ${grubdir}/user.cfg` ++ prefix="GRUB2_PASSWORD=" ++ ++ stty -echo ++ echo -n "Enter Current password: " ++ read PASSWORD_CURRENT ++ echo ++ ++ needcheckpass="${prefix}$(getsaltpass "${PASSWORD_CURRENT}" "${PASSWORD_CURRENT}" "${expectsalt}")" ++ if [ "$expectpass" != "$needcheckpass" ]; then ++ echo "Authentication failed" ++ exit 1 ++ fi ++ ++ stty ${ttyopt} ++} ++ ++verifygrubcfgoldpasswd() { ++ # get old password line ++ expectpass=`cat ${grubdir}/grub.cfg | grep "password_pbkdf2 root grub.pbkdf2.sha512" | cut -d " " -f 3` ++ # if not get password, try a quotation mark match ++ if [ -z "$expectpass" ];then ++ expectpass=`cat ${grubdir}/grub.cfg | grep "password_pbkdf2 root \"grub.pbkdf2.sha512" | cut -d " " -f 3 | cut -d "\"" -f 2` ++ fi ++ if [ -z "$expectpass" ];then ++ expectpass=`cat ${grubdir}/grub.cfg | grep "password_pbkdf2 root 'grub.pbkdf2.sha512" | cut -d " " -f 3 | cut -d "'" -f 2` ++ fi ++ if [ -n "$expectpass" ];then ++ # get old password salt ++ expectsalt=`echo ${expectpass} | cut -d "." -f 5` ++ stty -echo ++ echo -n "Enter Current password: " ++ read PASSWORD_CURRENT ++ echo ++ ++ needcheckpass="$(getsaltpass "${PASSWORD_CURRENT}" "${PASSWORD_CURRENT}" "${expectsalt}")" ++ if [ "$expectpass" != "$needcheckpass" ]; then ++ echo "Authentication failed" ++ exit 1 ++ fi ++ fi ++ ++} ++ ++if [ -e ${grubdir}/user.cfg ];then ++ verifyusercfgoldpasswd ++else ++ verifygrubcfgoldpasswd ++fi ++ ++checkcomplexity() { ++ set +e ++ USERNAME=`cat ${grubdir}/grub.cfg | grep "set superusers=" | cut -d "\"" -f 2 |tail -1` ++ local P1="$1" && shift ++ if [ "$P1" = "$USERNAME" ];then ++ echo "The password contains the user name in some form" ++ exit 1 ++ fi ++ # password len >= 8 ++ strlen=`echo "$P1" | grep -E '^(.{8,}).*$'` ++ if [ -z "$strlen" ];then ++ echo "The password is shorter than 8 characters" ++ exit 1 ++ fi ++ # lowercase ++ strlow=`echo "$P1" | grep -E --color '^(.*[a-z]+).*$'` ++ # uppercase ++ strupp=`echo $P1 | grep -E --color '^(.*[A-Z]).*$'` ++ # special character ++ strts=`echo $P1 | grep -E --color '^(.*\W).*$'` ++ # num ++ strnum=`echo $P1 | grep -E --color '^(.*[0-9]).*$'` ++ complexity=0 ++ if [ -n "$strlow" ];then ++ complexity=`expr $complexity + 1` ++ fi ++ if [ -n "$strupp" ];then ++ complexity=`expr $complexity + 1` ++ fi ++ if [ -n "$strts" ];then ++ complexity=`expr $complexity + 1` ++ fi ++ if [ -n "$strnum" ];then ++ complexity=`expr $complexity + 1` ++ fi ++ if [ $complexity -lt 3 ];then ++ echo "The password contains less than 3 character classes" ++ exit 1 ++ fi ++ set -e ++} ++ + stty -echo + + # prompt & confirm new grub2 root user password + echo -n "Enter password: " + read PASSWORD + echo ++stty ${ttyopt} ++checkcomplexity $PASSWORD ++stty -echo + echo -n "Confirm password: " + read PASSWORD_CONFIRM + echo + stty ${ttyopt} ++checkcomplexity $PASSWORD_CONFIRM + + getpass() { + local P0 +-- +2.33.0 + diff --git a/grub2.spec b/grub2.spec index 788a643..15fb21f 100644 --- a/grub2.spec +++ b/grub2.spec @@ -14,7 +14,7 @@ Name: grub2 Epoch: 1 Version: 2.12 -Release: 3 +Release: 4 Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -449,6 +449,12 @@ fi %{_datadir}/man/man* %changelog +* Mon Mar 11 2024 zhangqiumiao - 1:2.12-4 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:Don't require a password to boot entries generated by grub-mkconfig + * Fri Mar 8 2024 zhangqiumiao - 1:2.12-3 - Type:bugfix - CVE:NA -- Gitee