@@ -647,7 +647,7 @@ static void parse_spl_header(const uint32_t spl_addr)
* import -t" the string(s) at fel_script_address right away.
*/
himport_r(&env_htab, (char *)(uintptr_t)spl->fel_script_address,
- spl->fel_uEnv_length, '\n', H_NOCLEAR, 0, 0, NULL);
+ spl->fel_uEnv_length, '\n', H_NOCLEAR, 0, 0, NULL, 0);
return;
}
/* otherwise assume .scr format (mkimage-type script) */
@@ -1079,7 +1079,7 @@ static int do_env_import(cmd_tbl_t *cmdtp, int flag,
}
if (himport_r(&env_htab, ptr, size, sep, del ? 0 : H_NOCLEAR,
- crlf_is_lf, 0, NULL) == 0) {
+ crlf_is_lf, 0, NULL, false) == 0) {
pr_err("Environment import failed: errno = %d\n", errno);
return 1;
}
@@ -83,7 +83,7 @@ void set_default_env(const char *s)
if (himport_r(&env_htab, (char *)default_environment,
sizeof(default_environment), '\0', flags, 0,
- 0, NULL) == 0)
+ 0, NULL, false) == 0)
pr_err("Environment import failed: errno = %d\n", errno);
gd->flags |= GD_FLG_ENV_READY;
@@ -100,7 +100,7 @@ int set_default_vars(int nvars, char * const vars[])
*/
return himport_r(&env_htab, (const char *)default_environment,
sizeof(default_environment), '\0',
- H_NOCLEAR | H_INTERACTIVE, 0, nvars, vars);
+ H_NOCLEAR | H_INTERACTIVE, 0, nvars, vars, 0);
}
#ifdef CONFIG_ENV_AES
@@ -178,7 +178,7 @@ int env_import(const char *buf, int check)
}
if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0, 0,
- 0, NULL)) {
+ 0, NULL, false)) {
gd->flags |= GD_FLG_ENV_READY;
return 1;
}
@@ -101,7 +101,7 @@ extern ssize_t hexport_r(struct hsearch_data *__htab,
extern int himport_r(struct hsearch_data *__htab,
const char *__env, size_t __size, const char __sep,
int __flag, int __crlf_is_lf, int nvars,
- char * const vars[]);
+ char * const vars[], bool whitelisting);
/* Walk the whole table calling the callback on each element */
extern int hwalk_r(struct hsearch_data *__htab, int (*callback)(ENTRY *));
@@ -772,11 +772,17 @@ static int drop_var_from_set(const char *name, int nvars, char * vars[])
*
* In theory, arbitrary separator characters can be used, but only
* '\0' and '\n' have really been tested.
+ *
+ * "whitelisting" makes the function to not remove variables from the
+ * env that were not found in "vars".
+ * if "whitelisting" is false, the function remove variables from env
+ * that were not found in "vars".
*/
int himport_r(struct hsearch_data *htab,
const char *env, size_t size, const char sep, int flag,
- int crlf_is_lf, int nvars, char * const vars[])
+ int crlf_is_lf, int nvars, char * const vars[],
+ bool whitelisting)
{
char *data, *sp, *dp, *name, *value;
char *localvars[nvars];
@@ -935,6 +941,14 @@ int himport_r(struct hsearch_data *htab,
free(data);
/* process variables which were not considered */
+ /*
+ * If we are importing variables from a second env and checking they're
+ * whitelisted, we don't want to delete the variables in current env
+ * because it was not in the whitelist.
+ */
+ if (whitelisting)
+ goto out;
+
for (i = 0; i < nvars; i++) {
if (localvars[i] == NULL)
continue;
@@ -952,6 +966,7 @@ int himport_r(struct hsearch_data *htab,
printf("WARNING: '%s' not in imported env, deleting it!\n", localvars[i]);
}
+out:
debug("INSERT: done\n");
return 1; /* everything OK */
}
When passing the vars array to himport_r, variables in the array that are not in the loaded environment are removed from the current environment. Of course, this isn't suitable for whitelisting some variables. Let's introduce a whitelisting boolean that will not remove array variables that are not in the loaded environment from the current environment. The remaining of the code will rightfully override any variable that already exists. Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com> --- board/sunxi/board.c | 2 +- cmd/nvedit.c | 2 +- env/common.c | 6 +++--- include/search.h | 2 +- lib/hashtable.c | 17 ++++++++++++++++- 5 files changed, 22 insertions(+), 7 deletions(-)