summaryrefslogtreecommitdiff
path: root/tools/env/fw_env.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/env/fw_env.c')
-rw-r--r--tools/env/fw_env.c92
1 files changed, 75 insertions, 17 deletions
diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c
index 9b023e807b..90c7a5d3f3 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