]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Basic menuentry-retrieveing jail
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 16 Sep 2010 21:48:32 +0000 (23:48 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 16 Sep 2010 21:48:32 +0000 (23:48 +0200)
grub-core/commands/configfile.c
grub-core/commands/menuentry.c
grub-core/commands/search_wrap.c
grub-core/commands/test.c
grub-core/kern/corecmd.c
grub-core/normal/context.c
grub-core/script/execute.c
include/grub/command.h
include/grub/env.h
include/grub/err.h
include/grub/normal.h

index 469447711457eb31b55cebc6166f8231203ca6da..4d54ae682b8152d302d0db4d4bbeb1f6beb895f1 100644 (file)
 static grub_err_t
 grub_cmd_source (grub_command_t cmd, int argc, char **args)
 {
-  int new_env;
+  int new_env, jail;
 
   if (argc != 1)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
 
-  new_env = (cmd->name[0] == 'c');
+  jail = (cmd->name[0] == 'j');
+  new_env = (cmd->name[jail ? 5 : 0] == 'c');
 
   if (new_env)
-    {
-      grub_cls ();
-      grub_env_context_open (1);
-    }
+    grub_cls ();
+
+  if (new_env && !jail)
+    grub_env_context_open ();
+  if (jail)
+    grub_env_jail_open (!new_env);
 
   grub_normal_execute (args[0], 1, ! new_env);
 
-  if (new_env)
+  if (new_env && !jail)
     grub_env_context_close ();
+  if (jail)
+    grub_env_jail_close (!new_env);
 
   return 0;
 }
 
 static grub_command_t cmd_configfile, cmd_source, cmd_dot;
+static grub_command_t cmd_jail_source, cmd_jail_configfile;
 \f
 GRUB_MOD_INIT(configfile)
 {
@@ -60,6 +66,19 @@ GRUB_MOD_INIT(configfile)
                           N_("FILE"),
                           N_("Load another config file without changing context.")
                           );
+
+  cmd_jail_source =
+    grub_register_command ("jail_source", grub_cmd_source,
+                          N_("FILE"),
+                          N_("Load another config file without changing context but take only menuentries.")
+                          );
+
+  cmd_jail_configfile =
+    grub_register_command ("jail_configfile", grub_cmd_source,
+                          N_("FILE"),
+                          N_("Load another config file without changing context but take only menuentries.")
+                          );
+
   cmd_dot =
     grub_register_command (".", grub_cmd_source,
                           N_("FILE"),
@@ -71,5 +90,7 @@ GRUB_MOD_FINI(configfile)
 {
   grub_unregister_command (cmd_configfile);
   grub_unregister_command (cmd_source);
+  grub_unregister_command (cmd_jail_configfile);
+  grub_unregister_command (cmd_jail_source);
   grub_unregister_command (cmd_dot);
 }
index 9c4139d7de50f430533333f48d33ad1000a5559c..3f6f295bcc5b37c9e7012bd21a765853c80f1266 100644 (file)
@@ -274,7 +274,8 @@ void
 grub_menu_init (void)
 {
   cmd = grub_register_extcmd ("menuentry", grub_cmd_menuentry,
-                             GRUB_COMMAND_FLAG_BLOCKS,
+                             GRUB_COMMAND_FLAG_BLOCKS
+                             | GRUB_COMMAND_FLAG_UNJAILED,
                              N_("BLOCK"), N_("Define a menuentry."), options);
 }
 
index 402421f652b070735c62fa3d9ad1a4acc23f4a23..a06399ac6723f843c48c30c7fa654f6118d98208 100644 (file)
@@ -90,7 +90,7 @@ static grub_extcmd_t cmd;
 GRUB_MOD_INIT(search)
 {
   cmd =
-    grub_register_extcmd ("search", grub_cmd_search, 0,
+    grub_register_extcmd ("search", grub_cmd_search, GRUB_COMMAND_FLAG_UNJAILED,
                          N_("[-f|-l|-u|-s|-n] [--hint HINT [--hint HINT] ...]"
                             " NAME"),
                          N_("Search devices by file, filesystem label"
index 97b7fe6e4fef66928ff032003084da32feb0055a..3affab9c518d38656eeaedc857d3d3308fb66f56 100644 (file)
@@ -423,8 +423,10 @@ GRUB_MOD_INIT(test)
 {
   cmd_1 = grub_register_command ("[", grub_cmd_test,
                                 N_("EXPRESSION ]"), N_("Evaluate an expression."));
+  cmd_1->flags |= GRUB_COMMAND_FLAG_UNJAILED;
   cmd_2 = grub_register_command ("test", grub_cmd_test,
                                 N_("EXPRESSION"), N_("Evaluate an expression."));
+  cmd_2->flags |= GRUB_COMMAND_FLAG_UNJAILED;
 }
 
 GRUB_MOD_FINI(test)
index 8675248d3bfc5f86aeaf0c938cfacac5dbae23cc..f1d060cef61ec2e4dc9a1dbc46a9ad75f767ec0d 100644 (file)
@@ -178,9 +178,12 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
 void
 grub_register_core_commands (void)
 {
-  grub_register_command ("set", grub_core_cmd_set,
-                        N_("[ENVVAR=VALUE]"),
-                        N_("Set an environment variable."));
+  grub_command_t cmd;
+  cmd = grub_register_command ("set", grub_core_cmd_set,
+                              N_("[ENVVAR=VALUE]"),
+                              N_("Set an environment variable."));
+  if (cmd)
+    cmd->flags |= GRUB_COMMAND_FLAG_UNJAILED;
   grub_register_command ("unset", grub_core_cmd_unset,
                         N_("ENVVAR"),
                         N_("Remove an environment variable."));
index ec718952d832eb18445a60e446db499e06486f52..3b182dde78dbde7ac3d54370175d37105ec44f6d 100644 (file)
@@ -52,8 +52,8 @@ grub_env_set_menu (grub_menu_t nmenu)
   current_menu->menu = nmenu;
 }
 
-grub_err_t
-grub_env_context_open (int export)
+static grub_err_t
+grub_env_new_context (int export_all)
 {
   struct grub_env_context *context;
   int i;
@@ -78,23 +78,36 @@ grub_env_context_open (int export)
       struct grub_env_var *var;
 
       for (var = context->prev->vars[i]; var; var = var->next)
-       {
-         if (export && var->global)
-           {
-             if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE)
-               {
-                 grub_env_context_close ();
-                 return grub_errno;
-               }
-             grub_env_export (var->name);
-             grub_register_variable_hook (var->name, var->read_hook, var->write_hook);
-           }
-       }
+       if (var->global || export_all)
+         {
+           if (grub_env_set (var->name, var->value) != GRUB_ERR_NONE)
+             {
+               grub_env_context_close ();
+               return grub_errno;
+             }
+           grub_env_export (var->name);
+           grub_register_variable_hook (var->name, var->read_hook, var->write_hook);
+         }
     }
 
   return GRUB_ERR_NONE;
 }
 
+grub_err_t
+grub_env_context_open (void)
+{
+  return grub_env_new_context (0);
+}
+
+int grub_jail_level = 0;
+
+grub_err_t
+grub_env_jail_open (int source)
+{
+  grub_jail_level++;
+  return grub_env_new_context (source);
+}
+
 grub_err_t
 grub_env_context_close (void)
 {
@@ -132,6 +145,36 @@ grub_env_context_close (void)
   return GRUB_ERR_NONE;
 }
 
+grub_err_t
+grub_env_jail_close (int source)
+{
+  grub_menu_t menu, menu2;
+  grub_menu_entry_t *last;
+  grub_err_t err;
+
+  if (source)
+    {
+      menu = grub_env_get_menu ();
+      grub_env_unset_menu ();
+    }
+  err = grub_env_context_close ();
+
+  if (source)
+    {
+      menu2 = grub_env_get_menu ();
+      
+      last = &menu2->entry_list;
+      while (*last)
+       last = &(*last)->next;
+      
+      *last = menu->entry_list;
+      menu2->size += menu->size;
+    }
+
+  grub_jail_level--;
+  return err;
+}
+
 grub_err_t
 grub_env_export (const char *name)
 {
index e24c4b1af0e5204eada5f973f2f6a04898a85328..8d64962f8a5948fdbf81ec750ae4834430bdb817 100644 (file)
@@ -611,8 +611,11 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
   /* Execute the GRUB command or function.  */
   if (grubcmd)
     {
-      if ((grubcmd->flags & GRUB_COMMAND_FLAG_BLOCKS) &&
-         (grubcmd->flags & GRUB_COMMAND_FLAG_EXTCMD))
+      if (grub_jail_level && !(grubcmd->flags & GRUB_COMMAND_FLAG_UNJAILED))
+       ret = grub_error (GRUB_ERR_JAIL, "%s isn't allowed to execute in jail",
+                         cmdname);
+      else if ((grubcmd->flags & GRUB_COMMAND_FLAG_BLOCKS) &&
+              (grubcmd->flags & GRUB_COMMAND_FLAG_EXTCMD))
        ret = grub_extcmd_dispatcher (grubcmd, argc, args, argv.script);
       else
        ret = (grubcmd->func) (grubcmd, argc, args);
index 3b7bf0a104f700bcbacb7f5dfe1d2ea22da5cd18..b17b1aa94242bd11ade43100db6f1fa6d034e981 100644 (file)
@@ -35,6 +35,8 @@ typedef enum grub_command_flags
     GRUB_COMMAND_ACCEPT_DASH = 0x80,
     /* This command accepts only options preceding direct arguments.  */
     GRUB_COMMAND_OPTIONS_AT_START = 0x100,
+    /* Can be executed in a jail.  */
+    GRUB_COMMAND_FLAG_UNJAILED = 0x200
   } grub_command_flags_t;
 
 struct grub_command;
index ae4fd8745a5bfa8192244f42aedbe9914e0c04a8..ee0e0546e4aef817a24ef316df99ecfd445789c4 100644 (file)
@@ -51,7 +51,7 @@ grub_err_t EXPORT_FUNC(grub_register_variable_hook) (const char *name,
                                                     grub_env_read_hook_t read_hook,
                                                     grub_env_write_hook_t write_hook);
 
-grub_err_t grub_env_context_open (int export);
+grub_err_t grub_env_context_open (void);
 grub_err_t grub_env_context_close (void);
 grub_err_t grub_env_export (const char *name);
 
@@ -59,4 +59,11 @@ void grub_env_unset_menu (void);
 grub_menu_t grub_env_get_menu (void);
 void grub_env_set_menu (grub_menu_t nmenu);
 
+grub_err_t
+grub_env_jail_open (int source);
+
+grub_err_t
+grub_env_jail_close (int source);
+
+
 #endif /* ! GRUB_ENV_HEADER */
index d35bba4747237a9dd5baa424e0f8be1ccabc6e18..18dc91efef4ee1f1696e85acdb956a289e0b07c4 100644 (file)
@@ -54,7 +54,8 @@ typedef enum
     GRUB_ERR_MENU,
     GRUB_ERR_TIMEOUT,
     GRUB_ERR_IO,
-    GRUB_ERR_ACCESS_DENIED
+    GRUB_ERR_ACCESS_DENIED,
+    GRUB_ERR_JAIL
   }
 grub_err_t;
 
index 51ab46b12dab13764db612bb741a8f0bd5f39bb4..7c99951c63bcb99bcc6222b2cf3526f498babe88 100644 (file)
@@ -115,4 +115,6 @@ void grub_normal_reset_more (void);
 
 void grub_xputs_normal (const char *str);
 
+extern int grub_jail_level;
+
 #endif /* ! GRUB_NORMAL_HEADER */