Since GRUB supports multi-level menu entries:
In order to enable authentication support, the "superusers"
variable and "--unrestricted" in menu entry has been set, but GRUB
authentication only works in the top-level menu entry. When entering a menu
entry with "--unrestricted" set, users can still edit menu entry and enter a
GRUB shell, which I thought was a problem. After checking the code, I found the
reason is that the "superusers" variable was NULL in the submenu, which caused
the authentication function is_authenticated() to return 1, thus skipping
authentication.
Solution: Save "superusers" variable when switching menu entry, and
unauthenticate when returning to the higher-level menu entry.*
grub-core/normal/menu.c (grub_menu_execute_entry): Save "superusers" variable
and disable authentication when returning to the last menu entry.
* grub-core/normal/menu.c (grub_show_menu): control whether to authenticate via
"force_auth".
* grub-core/commands/legacycfg.c (grub_cmd_legacy_source): enable
authentication by default (keep previous).
* grub-core/commands/syslinuxcfg.c (grub_cmd_syslinux_source): Likewise.
* grub-core/normal/main.c (grub_normal_execute): Likewise.
* grub-core/normal/menu_entry.c (run): Likewise.
Signed-off-by: zhouzilong <zhouzil...@uniontech.com>
---
grub-core/commands/legacycfg.c | 2 +-
grub-core/commands/syslinuxcfg.c | 2 +-
grub-core/normal/main.c | 2 +-
grub-core/normal/menu.c | 25
+++++++++++++++----------
grub-core/normal/menu_entry.c | 2 +-
include/grub/normal.h | 2
+-
6 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c
index cc5971f4d..ee6ff8f52 100644
--- a/grub-core/commands/legacycfg.c
+++ b/grub-core/commands/legacycfg.c
@@ -246,7 +246,7 @@ grub_cmd_legacy_source (struct grub_command *cmd,
grub_menu_t menu;
menu = grub_env_get_menu ();
if (menu && menu->size)
- grub_show_menu (menu, 1, 0);
+ grub_show_menu (menu, 1, 0, 1);
if (!extractor)
grub_env_context_close ();
}
diff --git a/grub-core/commands/syslinuxcfg.c b/grub-core/commands/syslinuxcfg.c
index 7be28fada..e88a00ef6 100644
--- a/grub-core/commands/syslinuxcfg.c
+++ b/grub-core/commands/syslinuxcfg.c
@@ -164,7 +164,7 @@ grub_cmd_syslinux_source (grub_extcmd_context_t ctxt,
grub_menu_t menu;
menu = grub_env_get_menu ();
if (menu && menu->size)
- grub_show_menu (menu, 1, 0);
+ grub_show_menu (menu, 1, 0, 1);
if (!extractor)
grub_env_context_close ();
}
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
index c4ebe9e22..d87faf308 100644
--- a/grub-core/normal/main.c
+++ b/grub-core/normal/main.c
@@ -288,7 +288,7 @@ grub_normal_execute (const char *config, int nested, int
batch)
{
grub_boot_time ("Entering menu");
- grub_show_menu (menu, nested, 0);
+ grub_show_menu (menu, nested, 0, 1);
if (nested)
grub_normal_free_menu (menu);
}
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
index 8397886fa..71b09d512 100644
--- a/grub-core/normal/menu.c
+++ b/grub-core/normal/menu.c
@@ -208,7 +208,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int
auto_boot)
int errs_before;
grub_menu_t menu = NULL;
char *optr, *buf, *oldchosen = NULL, *olddefault = NULL;
- const char *ptr, *chosen, *def;
+ const char *ptr, *chosen, *def, *superusers;
grub_size_t sz = 0;
if (entry->restricted)
@@ -225,6 +225,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int
auto_boot)
chosen = grub_env_get ("chosen");
def = grub_env_get ("default");
+ superusers = grub_env_get ("superusers");
if (entry->submenu)
{
@@ -294,6 +295,8 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int
auto_boot)
else
grub_env_unset ("default");
+ grub_env_set ("superusers", superusers);
+
grub_script_execute_new_scope (entry->sourcecode,
entry->argc, entry->args);
if (errs_before != grub_err_printed_errors)
@@ -312,7 +315,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int
auto_boot)
{
if (menu && menu->size)
{
- grub_show_menu (menu, 1, auto_boot);
+ grub_show_menu (menu, 1, auto_boot, 0);
grub_normal_free_menu (menu);
}
grub_env_context_close ();
@@ -884,7 +887,7 @@ show_menu (grub_menu_t menu, int nested, int autobooted)
}
grub_err_t
-grub_show_menu (grub_menu_t menu, int nested, int autoboot)
+grub_show_menu (grub_menu_t menu, int nested, int autoboot, int force_auth)
{
grub_err_t err1, err2;
@@ -897,13 +900,15 @@ grub_show_menu (grub_menu_t menu, int nested, int
autoboot)
if (grub_normal_exit_level)
break;
- err2 = grub_auth_check_authentication (NULL);
- if (err2)
- {
- grub_print_error ();
- grub_errno = GRUB_ERR_NONE;
- continue;
- }
+ if (force_auth) {
+ err2 = grub_auth_check_authentication (NULL);
+ if (err2)
+ {
+ grub_print_error ();
+ grub_errno = GRUB_ERR_NONE;
+ continue;
+ }
+ }
break;
}
diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
index 50eef918c..1a0595fc3 100644
--- a/grub-core/normal/menu_entry.c
+++ b/grub-core/normal/menu_entry.c
@@ -1227,7 +1227,7 @@ run (struct screen *screen)
{
if (menu && menu->size)
{
- grub_show_menu (menu, 1, 0);
+ grub_show_menu (menu, 1, 0, 1);
grub_normal_free_menu (menu);
}
grub_env_context_close ();
diff --git a/include/grub/normal.h b/include/grub/normal.h
index 218cbabcc..58daf3d25 100644
--- a/include/grub/normal.h
+++ b/include/grub/normal.h
@@ -113,7 +113,7 @@ void grub_print_message_indented (const char *msg, int
margin_left,
void
grub_menu_text_register_instances (int entry, grub_menu_t menu, int
nested);
grub_err_t
-grub_show_menu (grub_menu_t menu, int nested, int autobooted);
+grub_show_menu (grub_menu_t menu, int nested, int autobooted, int force_auth);
/* Defined in `handler.c'. */
void read_handler_list (void);
--
2.20.1
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel