From patchwork Fri Dec 22 21:13:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 122663 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2745404qgn; Fri, 22 Dec 2017 13:17:25 -0800 (PST) X-Google-Smtp-Source: ACJfBosdcbMtZYcKfWSbn/B+dgXmK3taL7BudgMac8dnN8Z2QbXWU16yUSHCOWWyNWbNPeaotESM X-Received: by 10.80.134.108 with SMTP id 41mr17176863edt.69.1513977445780; Fri, 22 Dec 2017 13:17:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513977445; cv=none; d=google.com; s=arc-20160816; b=exUfUCIiux6NGQpQsfYA9AiJeN6HAnf2ebpsTFei3Qo1Y7ZyAg5alEcXlMLA25ea2W Q+XKAba4p65cgQLFl2YdadJb0+2tLIO1VRBDRMh99fod2q0foRSh03dF07QnH17HWgwC 6f0LFX45YvzQ7afhYE6B0VSX/3oCuKlJVEwsaWLDikogUaJYTw97WowuGn0oseXBs57v g5G5GhCPnITxMxgfGrvU6s716hi0LtimfE0EqIqU5UQgI8AyIVVpHLTEdr329/Ixr8f6 /HBCF8tNVXnru6hXHX24RIFHYjXSmerVdyMj5iP5+Yosk6OvyodaQ+MZ3hj5pgzsis2k 2Uxg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:cc:references:in-reply-to:references :in-reply-to:message-id:date:to:from:arc-authentication-results; bh=QBQn47/sbm16JAv6i1tPTWAunEBUisyhzeszRPb0/j8=; b=Ps0aNZevMpRSdFnTCuB6ltgtwoKQ5lW5Xo8O5MqNhbV9xOBBaF2ud1RvCewgL7VEM7 AsZilma/DOWF4gE2gNwLh9EsezR+fKiNqssVOyqz70Z7XfTlrTmrhcq3d7KjQk3Vx8Rw jftaHQrk9uHee/2V1QsENpzc1KcCRYzbmhQoWZJBWanzMDHIFxHgPe4QF3mfsx81oScd 82mvi/YLRGFRpIusBHZBnxapRftFcHl+yueCZGY8OWePiH+mRVXhMo5jEWUvroN7+PHM 20N8/r3R/SY/wctF1svMPv3XdFdDM5UTwmz33QPUDgD3V5Q7CJsdWLVmWF+3IOhVssVC 9IKw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de Return-Path: Received: from lists.denx.de (dione.denx.de. [81.169.180.215]) by mx.google.com with ESMTP id f15si1155205edl.101.2017.12.22.13.17.25; Fri, 22 Dec 2017 13:17:25 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) client-ip=81.169.180.215; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by lists.denx.de (Postfix, from userid 105) id 59571C21F76; Fri, 22 Dec 2017 21:15:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 87332C22200; Fri, 22 Dec 2017 21:14:19 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 03DB4C21F2D; Fri, 22 Dec 2017 21:14:14 +0000 (UTC) Received: from mail.free-electrons.com (mail.free-electrons.com [62.4.15.54]) by lists.denx.de (Postfix) with ESMTP id A172BC21EF1 for ; Fri, 22 Dec 2017 21:14:14 +0000 (UTC) Received: by mail.free-electrons.com (Postfix, from userid 110) id C67BD207CA; Fri, 22 Dec 2017 22:14:13 +0100 (CET) Received: from localhost.localdomain (unknown [80.12.41.248]) by mail.free-electrons.com (Postfix) with ESMTPSA id 2EBE3203A1; Fri, 22 Dec 2017 22:14:13 +0100 (CET) From: Quentin Schulz To: jagan@openedev.com, maxime.ripard@free-electrons.com, hdegoede@redhat.com, sjg@chromium.org, wd@denx.de, andre.przywara@arm.com, lukma@denx.de Date: Fri, 22 Dec 2017 22:13:37 +0100 Message-Id: <45316f927ce86b20958468367f7d642a76f32888.1513975247.git-series.quentin.schulz@free-electrons.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: References: In-Reply-To: References: Cc: thomas.petazzoni@free-electrons.com, u-boot@lists.denx.de Subject: [U-Boot] [PATCH 03/11] env: add support for whitelisting variables from secondary environments X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This patch makes it possible to have a first environment that will be the base environment, secondary environment that will be pre-loaded and have its variables passing through the whitelist "mask" to override variables in the base environment. The base environment will be the environment with the highest priority (0 is highest) that can load and the next loadable environment will be the secondary environment (with a lowest priority than the base environment of course). The whitelist "mask" is built with the content of space-separated list of environment variables in ENV_VAR_WHITELIST_LIST in Kconfig. Signed-off-by: Quentin Schulz --- env/Kconfig | 17 +++++++- env/common.c | 7 +++- env/env.c | 100 +++++++++++++++++++++++++++++++++++++++---- include/environment.h | 6 +++- 4 files changed, 123 insertions(+), 7 deletions(-) diff --git a/env/Kconfig b/env/Kconfig index 1952463..d57594d 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -438,4 +438,21 @@ config ENV_UBI_VOLUME endif +config ENV_VAR_WHITELIST + bool "Enable overriding some variables from secondary environments" + help + This allows overriding some variables from secondary environments. + After the first valid environment is loaded, a secondary environment + is pre-loaded and its variables that are present in the whitelist will + be added to the current environment or will override existing + variables. + +config ENV_VAR_WHITELIST_LIST + depends on ENV_VAR_WHITELIST + string "Whitelist of variables from secondary environments" + help + This defines the variables that are allowed to be overriden by + ones from secondary environments. + This is a list of environment variables that are space-separated. + endmenu diff --git a/env/common.c b/env/common.c index 9d97541..00c454d 100644 --- a/env/common.c +++ b/env/common.c @@ -177,8 +177,15 @@ int env_import(const char *buf, int check) return ret; } +#ifdef CONFIG_ENV_VAR_WHITELIST + if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', + whitelisting ? H_NOCLEAR : 0, 0, + whitelisting ? whitelist_nvars : 0, + whitelisting ? whitelist : NULL, whitelisting)) { +#else if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0, 0, 0, NULL, false)) { +#endif gd->flags |= GD_FLG_ENV_READY; return 1; } diff --git a/env/env.c b/env/env.c index 5e70ddf..43a62b8 100644 --- a/env/env.c +++ b/env/env.c @@ -7,9 +7,18 @@ #include #include +#ifdef CONFIG_ENV_VAR_WHITELIST +# include +#endif DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_ENV_VAR_WHITELIST +char *const *whitelist; +bool whitelisting; +unsigned int whitelist_nvars; +#endif + static struct env_driver *_env_driver_lookup(enum env_location loc) { struct env_driver *drv; @@ -62,6 +71,31 @@ static enum env_location env_locations[] = { static enum env_location env_load_location; +#ifdef CONFIG_ENV_VAR_WHITELIST +void env_create_whitelist(void) +{ + char **wl_vars; + char *wl = strchr(CONFIG_ENV_VAR_WHITELIST_LIST, ' '); + unsigned int nvars = 0; + + while(wl) { + nvars++; + wl = strchr(wl + 1, ' '); + } + + whitelist_nvars = nvars + 1; + + wl_vars = malloc(sizeof(char *) * (nvars + 1)); + + wl_vars[nvars] = strtok(CONFIG_ENV_VAR_WHITELIST_LIST, " "); + while (nvars) { + wl_vars[--nvars] = strtok(NULL, " "); + } + + whitelist = wl_vars; +} +#endif + __weak enum env_location env_get_location(enum env_operation op, int prio) { switch (op) { @@ -74,7 +108,11 @@ __weak enum env_location env_get_location(enum env_operation op, int prio) return env_load_location = env_locations[prio]; case ENVO_SAVE: +#ifdef CONFIG_ENV_VAR_WHITELIST + return env_locations[prio]; +#else return env_load_location; +#endif } return ENVL_UNKNOWN; @@ -130,10 +168,12 @@ int env_load(void) { struct env_driver *drv; int prio; + int ret = 1; +#ifdef CONFIG_ENV_VAR_WHITELIST + bool found = false; +#endif for (prio = 0; (drv = env_driver_lookup(ENVO_LOAD, prio)); prio++) { - int ret; - if (!drv->load) continue; @@ -144,16 +184,52 @@ int env_load(void) ret = drv->load(); printf("%s\n", ret ? "Failed" : "OK"); if (!ret) - return 0; + break; } - return -ENODEV; + if (ret) + return -ENODEV; + +#ifdef CONFIG_ENV_VAR_WHITELIST + env_create_whitelist(); + + whitelisting = true; + /* When whitelisting, env from prio x+n will override env from prio x */ + for (prio++; prio < ARRAY_SIZE(env_locations); prio++) { + drv = env_driver_lookup(ENVO_LOAD, prio); + if (!drv) + continue; + + if (!drv->load) + continue; + + printf("Overriding env variables with ones from %s env...", + __func__, drv->name); + ret = drv->load(); + printf("%s\n", ret ? "Failed" : "OK"); + if (!ret) { + found = true; + continue; + } + } + +out: + if (!found) + debug("%s: Couldn't find other valid env for whitelisting\n", + __func__); + + whitelisting = false; +#endif + return 0; } int env_save(void) { struct env_driver *drv; int prio; +#ifdef CONFIG_ENV_VAR_WHITELIST + bool saved = false; +#endif for (prio = 0; (drv = env_driver_lookup(ENVO_SAVE, prio)); prio++) { int ret; @@ -167,13 +243,23 @@ int env_save(void) printf("Saving Environment to %s... ", drv->name); ret = drv->save(); printf("%s\n", ret ? "Failed" : "OK"); +#ifdef CONFIG_ENV_VAR_WHITELIST + /* When whitelisting, we want to save to all media available */ + if (!ret) { + saved = true; + continue; + } +#else if (!ret) return 0; - - debug("%s: Environment %s failed to save (err=%d)\n", __func__, - drv->name, ret); +#endif } +#ifdef CONFIG_ENV_VAR_WHITELIST + if (saved) + return 0; +#endif + return -ENODEV; } diff --git a/include/environment.h b/include/environment.h index 7fa8b98..33e47ba 100644 --- a/include/environment.h +++ b/include/environment.h @@ -267,6 +267,12 @@ struct env_driver { int (*init)(void); }; +#ifdef CONFIG_ENV_VAR_WHITELIST +extern char *const *whitelist; +extern unsigned int whitelist_nvars; +extern bool whitelisting; +#endif + /* Declare a new environment location driver */ #define U_BOOT_ENV_LOCATION(__name) \ ll_entry_declare(struct env_driver, __name, env_driver)