diff options
Diffstat (limited to 'tools/env/fw_env.c')
-rw-r--r-- | tools/env/fw_env.c | 92 |
1 files changed, 75 insertions, 17 deletions
diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 9b023e8..90c7a5d 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -25,6 +25,7 @@ */ #include <errno.h> +#include <env_flags.h> #include <fcntl.h> #include <linux/stringify.h> #include <stdio.h> @@ -181,6 +182,32 @@ char *fw_getenv (char *name) } /* + * Search the default environment for a variable. + * Return the value, if found, or NULL, if not found. + */ +char *fw_getdefenv(char *name) +{ + char *env, *nxt; + + for (env = default_environment; *env; env = nxt + 1) { + char *val; + + for (nxt = env; *nxt; ++nxt) { + if (nxt >= &default_environment[ENV_SIZE]) { + fprintf(stderr, "## Error: " + "default environment not terminated\n"); + return NULL; + } + } + val = envmatch(name, env); + if (!val) + continue; + return val; + } + return NULL; +} + +/* * Print the current definition of one, or more, or all * environment variables */ @@ -281,6 +308,7 @@ int fw_env_write(char *name, char *value) int len; char *env, *nxt; char *oldval = NULL; + int deleting, creating, overwriting; /* * search if variable with this name already exists @@ -298,27 +326,49 @@ int fw_env_write(char *name, char *value) break; } - /* - * Delete any existing definition - */ - if (oldval) { -#ifndef CONFIG_ENV_OVERWRITE - /* - * Ethernet Address and serial# can be set only once - */ - if ( - (strcmp(name, "serial#") == 0) || - ((strcmp(name, "ethaddr") == 0) -#if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR) - && (strcmp(oldval, __stringify(CONFIG_ETHADDR)) != 0) -#endif /* CONFIG_OVERWRITE_ETHADDR_ONCE && CONFIG_ETHADDR */ - ) ) { - fprintf (stderr, "Can't overwrite \"%s\"\n", name); + deleting = (oldval && !(value && strlen(value))); + creating = (!oldval && (value && strlen(value))); + overwriting = (oldval && (value && strlen(value))); + + /* check for permission */ + if (deleting) { + if (env_flags_validate_varaccess(name, + ENV_FLAGS_VARACCESS_PREVENT_DELETE)) { + printf("Can't delete \"%s\"\n", name); + errno = EROFS; + return -1; + } + } else if (overwriting) { + if (env_flags_validate_varaccess(name, + ENV_FLAGS_VARACCESS_PREVENT_OVERWR)) { + printf("Can't overwrite \"%s\"\n", name); + errno = EROFS; + return -1; + } else if (env_flags_validate_varaccess(name, + ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR)) { + const char *defval = fw_getdefenv(name); + + if (defval == NULL) + defval = ""; + if (strcmp(oldval, defval) + != 0) { + printf("Can't overwrite \"%s\"\n", name); + errno = EROFS; + return -1; + } + } + } else if (creating) { + if (env_flags_validate_varaccess(name, + ENV_FLAGS_VARACCESS_PREVENT_CREATE)) { + printf("Can't create \"%s\"\n", name); errno = EROFS; return -1; } -#endif /* CONFIG_ENV_OVERWRITE */ + } else + /* Nothing to do */ + return 0; + if (deleting || overwriting) { if (*++nxt == '\0') { *env = '\0'; } else { @@ -395,6 +445,9 @@ int fw_setenv(int argc, char *argv[]) name = argv[1]; + if (env_flags_validate_env_set_params(argc, argv) < 0) + return 1; + len = 0; for (i = 2; i < argc; ++i) { char *val = argv[i]; @@ -516,6 +569,11 @@ int fw_parse_script(char *fname) name, val ? val : " removed"); #endif + if (env_flags_validate_type(name, val) < 0) { + ret = -1; + break; + } + /* * If there is an error setting a variable, * try to save the environment and returns an error |