grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v3 2/3] load_env support for whitelisting which variables are rea


From: Jon McCune
Subject: [PATCH v3 2/3] load_env support for whitelisting which variables are read from an env file
Date: Fri, 6 Sep 2013 16:59:17 -0700

This gives load_env support for naming variables that is the same as save_env.
This is useful to prevent potentially unwanted variables within a grubenv file
from impacting the behavior of a configuration, especially if using
check_signatures=enforce but wishing to retain support for savedefault,
boot_once, and similar.

This version of this patch drops all direct interaction with the logic in
verify.c.  The author of grub.cfg must take care to disable and re-enable
check_signatures as appropriate.

Signed-off-by: Jon McCune <address@hidden>
---
 grub-core/commands/loadenv.c | 57 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 52 insertions(+), 5 deletions(-)

diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c
index a431499..5828f5f 100644
--- a/grub-core/commands/loadenv.c
+++ b/grub-core/commands/loadenv.c
@@ -122,15 +122,59 @@ set_var (const char *name, const char *value)
   return 0;
 }
 
+#define MAX_VAR_NAME 1024
+/* TODO: eliminate the need for these to be global */
+static grub_size_t whitelist_len = 0;
+static char **whitelist_vars = NULL;
+static int
+/* Assumptions: name, value, and each element of whitelist_vars[] are non-NULL
+   and NULL-terminated. */
+set_var_whitelist (const char *name, const char *value)
+{
+  grub_size_t i;
+  if (whitelist_len < 1 || whitelist_vars == NULL)
+    return GRUB_ERR_OUT_OF_RANGE;
+
+  /* search for 'name' in the whitelist */
+  for (i = 0; i < whitelist_len; i++)
+    {
+      if (0 == grub_strncmp (name, whitelist_vars[i], MAX_VAR_NAME))
+        {
+          /* TODO: also validate the characters in the variables */
+          grub_dprintf ("crypt", "set_var_whitelist APPOVED: %s=%s\n",
+                        name, value);
+          grub_env_set (name, value);
+          return 0;
+        }
+    }
+
+  grub_dprintf ("crypt",
+                "set_var_whitelist REFUSING TO SET name='%s' value='%s'\n",
+                name, value);
+  /* Still considered success */
+  return 0;
+}
+
+/* Load environment variables from a file.  Accepts a flag which can override
+   the file from which variables are read.  If additional parameters are passed
+   (argc > 0), then those are interpreted as a whitelist of environment
+   variables whose values can be changed based on the contents of the file, and
+   the file is never signature-checked.
+   Otherwise, all variables from the file are processed, and the file must be
+   properly signed when check_signatures=enforce. */
 static grub_err_t
-grub_cmd_load_env (grub_extcmd_context_t ctxt,
-                   int argc __attribute__ ((unused)),
-                   char **args __attribute__ ((unused)))
+grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args)
 {
   struct grub_arg_list *state = ctxt->state;
   grub_file_t file;
   grub_envblk_t envblk;
 
+  /* argc > 0 indicates caller provided a whitelist of variables to read */
+  if (argc > 0)
+    {
+      whitelist_len = (argc >= 0) ? argc : 0;
+      whitelist_vars = args;
+    }
   file = open_envblk_file ((state[0].set) ? state[0].arg : 0);
   if (!file)
     return grub_errno;
@@ -139,10 +183,12 @@ grub_cmd_load_env (grub_extcmd_context_t ctxt,
   if (!envblk)
     goto fail;
 
-  grub_envblk_iterate (envblk, set_var);
+  grub_envblk_iterate (envblk, argc > 0 ? set_var_whitelist : set_var);
   grub_envblk_close (envblk);
 
 fail:
+  whitelist_len = 0;
+  whitelist_vars = NULL;
   grub_file_close (file);
   return grub_errno;
 }
@@ -387,7 +433,8 @@ static grub_extcmd_t cmd_load, cmd_list, cmd_save;
 GRUB_MOD_INIT (loadenv)
 {
   cmd_load =
-    grub_register_extcmd ("load_env", grub_cmd_load_env, 0, N_("[-f FILE]"),
+    grub_register_extcmd ("load_env", grub_cmd_load_env, 0,
+                          N_("[-f FILE] [whitelisted_variable_name] [...]"),
                           N_("Load variables from environment block file."),
                           options);
   cmd_list =
-- 
1.8.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]