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&gt;
---
&nbsp;grub-core/commands/legacycfg.c &nbsp; | &nbsp;2 +-
&nbsp;grub-core/commands/syslinuxcfg.c | &nbsp;2 +-
&nbsp;grub-core/normal/main.c &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;2 +-
&nbsp;grub-core/normal/menu.c &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| 25 
+++++++++++++++----------
&nbsp;grub-core/normal/menu_entry.c &nbsp; &nbsp;| &nbsp;2 +-
&nbsp;include/grub/normal.h &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| &nbsp;2 
+-
&nbsp;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,
&nbsp; &nbsp; &nbsp; &nbsp;grub_menu_t menu;
&nbsp; &nbsp; &nbsp; &nbsp;menu = grub_env_get_menu ();
&nbsp; &nbsp; &nbsp; &nbsp;if (menu &amp;&amp; menu-&gt;size)
-       grub_show_menu (menu, 1, 0);
+       grub_show_menu (menu, 1, 0, 1);
&nbsp; &nbsp; &nbsp; &nbsp;if (!extractor)
&nbsp;  grub_env_context_close ();
&nbsp; &nbsp; &nbsp;}
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,
&nbsp; &nbsp; &nbsp; &nbsp;grub_menu_t menu;
&nbsp; &nbsp; &nbsp; &nbsp;menu = grub_env_get_menu ();
&nbsp; &nbsp; &nbsp; &nbsp;if (menu &amp;&amp; menu-&gt;size)
-       grub_show_menu (menu, 1, 0);
+       grub_show_menu (menu, 1, 0, 1);
&nbsp; &nbsp; &nbsp; &nbsp;if (!extractor)
&nbsp;  grub_env_context_close ();
&nbsp; &nbsp; &nbsp;}
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)
&nbsp;  {
&nbsp;
&nbsp;   &nbsp;grub_boot_time ("Entering menu");
-        &nbsp;grub_show_menu (menu, nested, 0);
+        &nbsp;grub_show_menu (menu, nested, 0, 1);
&nbsp;   &nbsp;if (nested)
&nbsp;   &nbsp; &nbsp;grub_normal_free_menu (menu);
&nbsp;  }
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)
&nbsp; &nbsp;int errs_before;
&nbsp; &nbsp;grub_menu_t menu = NULL;
&nbsp; &nbsp;char *optr, *buf, *oldchosen = NULL, *olddefault = NULL;
- &nbsp;const char *ptr, *chosen, *def;
+ &nbsp;const char *ptr, *chosen, *def, *superusers;
&nbsp; &nbsp;grub_size_t sz = 0;
&nbsp;
&nbsp; &nbsp;if (entry-&gt;restricted)
@@ -225,6 +225,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int 
auto_boot)
&nbsp;
&nbsp; &nbsp;chosen = grub_env_get ("chosen");
&nbsp; &nbsp;def = grub_env_get ("default");
+ &nbsp;superusers = grub_env_get ("superusers");
&nbsp;
&nbsp; &nbsp;if (entry-&gt;submenu)
&nbsp; &nbsp; &nbsp;{
@@ -294,6 +295,8 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int 
auto_boot)
&nbsp; &nbsp;else
&nbsp; &nbsp; &nbsp;grub_env_unset ("default");
&nbsp;
+ &nbsp;grub_env_set ("superusers", superusers);
+
&nbsp; &nbsp;grub_script_execute_new_scope (entry-&gt;sourcecode, 
entry-&gt;argc, entry-&gt;args);
&nbsp;
&nbsp; &nbsp;if (errs_before != grub_err_printed_errors)
@@ -312,7 +315,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int 
auto_boot)
&nbsp; &nbsp; &nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;if (menu &amp;&amp; menu-&gt;size)
&nbsp;  {
-        &nbsp;grub_show_menu (menu, 1, auto_boot);
+        &nbsp;grub_show_menu (menu, 1, auto_boot, 0);
&nbsp;   &nbsp;grub_normal_free_menu (menu);
&nbsp;  }
&nbsp; &nbsp; &nbsp; &nbsp;grub_env_context_close ();
@@ -884,7 +887,7 @@ show_menu (grub_menu_t menu, int nested, int autobooted)
&nbsp;}
&nbsp;
&nbsp;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)
&nbsp;{
&nbsp; &nbsp;grub_err_t err1, err2;
&nbsp;
@@ -897,13 +900,15 @@ grub_show_menu (grub_menu_t menu, int nested, int 
autoboot)
&nbsp; &nbsp; &nbsp; &nbsp;if (grub_normal_exit_level)
&nbsp;  break;
&nbsp;
- &nbsp; &nbsp; &nbsp;err2 = grub_auth_check_authentication (NULL);
- &nbsp; &nbsp; &nbsp;if (err2)
-       {
-        &nbsp;grub_print_error ();
-        &nbsp;grub_errno = GRUB_ERR_NONE;
-        &nbsp;continue;
-       }
+ &nbsp; &nbsp; &nbsp;if (force_auth) {
+ &nbsp; &nbsp; &nbsp; &nbsp;err2 = grub_auth_check_authentication (NULL);
+ &nbsp; &nbsp; &nbsp; &nbsp;if (err2)
+ &nbsp; &nbsp; &nbsp; &nbsp;{
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;grub_print_error ();
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;grub_errno = GRUB_ERR_NONE;
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;continue;
+ &nbsp; &nbsp; &nbsp; &nbsp;}
+ &nbsp; &nbsp; &nbsp;}
&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;break;
&nbsp; &nbsp; &nbsp;}
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)
&nbsp; &nbsp; &nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;if (menu &amp;&amp; menu-&gt;size)
&nbsp;  {
-        &nbsp;grub_show_menu (menu, 1, 0);
+        &nbsp;grub_show_menu (menu, 1, 0, 1);
&nbsp;   &nbsp;grub_normal_free_menu (menu);
&nbsp;  }
&nbsp; &nbsp; &nbsp; &nbsp;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,
&nbsp;void
&nbsp;grub_menu_text_register_instances (int entry, grub_menu_t menu, int 
nested);
&nbsp;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);
&nbsp;
&nbsp;/* Defined in `handler.c'. &nbsp;*/
&nbsp;void read_handler_list (void);
-- 
2.20.1
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to