diff options
| author | Joe Hershberger <joe.hershberger@ni.com> | 2012-12-11 22:16:34 -0600 | 
|---|---|---|
| committer | Tom Rini <trini@ti.com> | 2012-12-13 11:46:56 -0700 | 
| commit | 267541f776f1e2bec21681c6e39a4c93af9621cf (patch) | |
| tree | 861ff411eab98193f9914d30ec420628e79912e0 /tools/env/fw_env.c | |
| parent | fffad71bc489cf224eda6d826a1645423852ee45 (diff) | |
| download | olio-uboot-2014.01-267541f776f1e2bec21681c6e39a4c93af9621cf.tar.xz olio-uboot-2014.01-267541f776f1e2bec21681c6e39a4c93af9621cf.zip | |
env: Add support for access control to .flags
Add support for read-only, write-once, and change-default.
Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
Diffstat (limited to 'tools/env/fw_env.c')
| -rw-r--r-- | tools/env/fw_env.c | 74 | 
1 files changed, 70 insertions, 4 deletions
| diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 5be36fc35..a596a1b0d 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 |