From 30fd4fadb319d7c6d43d949e2d30ffaea46a60cf Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 11 Dec 2012 22:16:32 -0600 Subject: tools/env: Add environment variable flags support Currently just validates variable types as decimal, hexidecimal, boolean, ip address, and mac address. Call env_acl_validate_setenv_params() from setenv() in fw_env.c. If the entry is not found in the env .flags, then look in the static one. This allows the env to override the static definitions, but prevents the need to have every definition in the environment distracting you. Need to build in _ctype for isdigit for Linux. Signed-off-by: Joe Hershberger --- tools/env/fw_env.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tools/env/fw_env.c') diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 9b023e8..5be36fc 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -25,6 +25,7 @@ */ #include +#include #include #include #include @@ -395,6 +396,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 +520,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 -- cgit v1.1 From 267541f776f1e2bec21681c6e39a4c93af9621cf Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 11 Dec 2012 22:16:34 -0600 Subject: env: Add support for access control to .flags Add support for read-only, write-once, and change-default. Signed-off-by: Joe Hershberger --- tools/env/fw_env.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 4 deletions(-) (limited to 'tools/env/fw_env.c') diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 5be36fc..a596a1b 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -182,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 */ @@ -282,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 @@ -299,10 +326,49 @@ int fw_env_write(char *name, char *value) break; } - /* - * Delete any existing definition - */ - if (oldval) { + 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; + } + } else + /* Nothing to do */ + return 0; + + if (deleting || overwriting) { #ifndef CONFIG_ENV_OVERWRITE /* * Ethernet Address and serial# can be set only once -- cgit v1.1 From 1d6cd0a3f69b549a3fc7e735a045279e7a14947e Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 11 Dec 2012 22:16:37 -0600 Subject: env: Handle write-once ethaddr and serial# generically Use the variable access flags to implement the protection for ethaddr and serial# instead of hard-coding them. Signed-off-by: Joe Hershberger --- tools/env/fw_env.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'tools/env/fw_env.c') diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index a596a1b..90c7a5d 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -369,23 +369,6 @@ int fw_env_write(char *name, char *value) return 0; if (deleting || overwriting) { -#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); - errno = EROFS; - return -1; - } -#endif /* CONFIG_ENV_OVERWRITE */ - if (*++nxt == '\0') { *env = '\0'; } else { -- cgit v1.1