[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