diff options
Diffstat (limited to 'env')
-rw-r--r-- | env/Kconfig | 8 | ||||
-rw-r--r-- | env/flags.c | 62 |
2 files changed, 59 insertions, 11 deletions
diff --git a/env/Kconfig b/env/Kconfig index 1cae1ed..5d0a8ec 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -623,6 +623,14 @@ config ENV_APPEND with newly imported data. This may be used in combination with static flags to e.g. to protect variables which must not be modified. +config ENV_WRITEABLE_LIST + bool "Permit write access only to listed variables" + default n + help + If defined, only environment variables which explicitly set the 'w' + writeable flag can be written and modified at runtime. No variables + can be otherwise created, written or imported into the environment. + config ENV_ACCESS_IGNORE_FORCE bool "Block forced environment operations" default n diff --git a/env/flags.c b/env/flags.c index f7a5377..df4aed2 100644 --- a/env/flags.c +++ b/env/flags.c @@ -28,8 +28,15 @@ #define ENV_FLAGS_NET_VARTYPE_REPS "" #endif +#ifdef CONFIG_ENV_WRITEABLE_LIST +#define ENV_FLAGS_WRITEABLE_VARACCESS_REPS "w" +#else +#define ENV_FLAGS_WRITEABLE_VARACCESS_REPS "" +#endif + static const char env_flags_vartype_rep[] = "sdxb" ENV_FLAGS_NET_VARTYPE_REPS; -static const char env_flags_varaccess_rep[] = "aroc"; +static const char env_flags_varaccess_rep[] = + "aroc" ENV_FLAGS_WRITEABLE_VARACCESS_REPS; static const int env_flags_varaccess_mask[] = { 0, ENV_FLAGS_VARACCESS_PREVENT_DELETE | @@ -38,7 +45,11 @@ static const int env_flags_varaccess_mask[] = { ENV_FLAGS_VARACCESS_PREVENT_DELETE | ENV_FLAGS_VARACCESS_PREVENT_OVERWR, ENV_FLAGS_VARACCESS_PREVENT_DELETE | - ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR}; + ENV_FLAGS_VARACCESS_PREVENT_NONDEF_OVERWR, +#ifdef CONFIG_ENV_WRITEABLE_LIST + ENV_FLAGS_VARACCESS_WRITEABLE, +#endif + }; #ifdef CONFIG_CMD_ENV_FLAGS static const char * const env_flags_vartype_names[] = { @@ -56,6 +67,9 @@ static const char * const env_flags_varaccess_names[] = { "read-only", "write-once", "change-default", +#ifdef CONFIG_ENV_WRITEABLE_LIST + "writeable", +#endif }; /* @@ -130,21 +144,25 @@ enum env_flags_vartype env_flags_parse_vartype(const char *flags) */ enum env_flags_varaccess env_flags_parse_varaccess(const char *flags) { + enum env_flags_varaccess va_default = env_flags_varaccess_any; + enum env_flags_varaccess va; char *access; if (strlen(flags) <= ENV_FLAGS_VARACCESS_LOC) - return env_flags_varaccess_any; + return va_default; access = strchr(env_flags_varaccess_rep, flags[ENV_FLAGS_VARACCESS_LOC]); - if (access != NULL) - return (enum env_flags_varaccess) + if (access != NULL) { + va = (enum env_flags_varaccess) (access - &env_flags_varaccess_rep[0]); + return va; + } printf("## Warning: Unknown environment variable access method '%c'\n", flags[ENV_FLAGS_VARACCESS_LOC]); - return env_flags_varaccess_any; + return va_default; } /* @@ -152,17 +170,21 @@ enum env_flags_varaccess env_flags_parse_varaccess(const char *flags) */ enum env_flags_varaccess env_flags_parse_varaccess_from_binflags(int binflags) { + enum env_flags_varaccess va_default = env_flags_varaccess_any; + enum env_flags_varaccess va; int i; for (i = 0; i < ARRAY_SIZE(env_flags_varaccess_mask); i++) if (env_flags_varaccess_mask[i] == - (binflags & ENV_FLAGS_VARACCESS_BIN_MASK)) - return (enum env_flags_varaccess)i; + (binflags & ENV_FLAGS_VARACCESS_BIN_MASK)) { + va = (enum env_flags_varaccess)i; + return va; + } printf("Warning: Non-standard access flags. (0x%x)\n", binflags & ENV_FLAGS_VARACCESS_BIN_MASK); - return env_flags_varaccess_any; + return va_default; } static inline int is_hex_prefix(const char *value) @@ -326,13 +348,14 @@ enum env_flags_vartype env_flags_get_type(const char *name) enum env_flags_varaccess env_flags_get_varaccess(const char *name) { const char *flags_list = env_get(ENV_FLAGS_VAR); + enum env_flags_varaccess va_default = env_flags_varaccess_any; char flags[ENV_FLAGS_ATTR_MAX_LEN + 1]; if (env_flags_lookup(flags_list, name, flags)) - return env_flags_varaccess_any; + return va_default; if (strlen(flags) <= ENV_FLAGS_VARACCESS_LOC) - return env_flags_varaccess_any; + return va_default; return env_flags_parse_varaccess(flags); } @@ -426,7 +449,11 @@ void env_flags_init(struct env_entry *var_entry) int ret = 1; if (first_call) { +#ifdef CONFIG_ENV_WRITEABLE_LIST + flags_list = ENV_FLAGS_LIST_STATIC; +#else flags_list = env_get(ENV_FLAGS_VAR); +#endif first_call = 0; } /* look in the ".flags" and static for a reference to this variable */ @@ -523,6 +550,19 @@ int env_flags_validate(const struct env_entry *item, const char *newval, } /* check for access permission */ +#ifdef CONFIG_ENV_WRITEABLE_LIST + if (flag & H_DEFAULT) + return 0; /* Default env is always OK */ + + /* + * External writeable variables can be overwritten by external env, + * anything else can not be overwritten by external env. + */ + if ((flag & H_EXTERNAL) && + !(item->flags & ENV_FLAGS_VARACCESS_WRITEABLE)) + return 1; +#endif + #ifndef CONFIG_ENV_ACCESS_IGNORE_FORCE if (flag & H_FORCE) { printf("## Error: Can't force access to \"%s\"\n", name); |