+From 92c63984fc28ea1bb0939acfcb551f65d7bfddf7 Mon Sep 17 00:00:00 2001
+From: Dennis Groenen <tj.groenen@gmail.com>
+Date: Fri, 23 Dec 2011 20:34:22 +0100
+Subject: [PATCH] appletlib: parse /etc/environment prior to applet launch
+
+---
+ libbb/appletlib.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 files changed, 117 insertions(+), 0 deletions(-)
+
+diff --git a/libbb/appletlib.c b/libbb/appletlib.c
+index 8157b4f..d13aee5 100644
+--- a/libbb/appletlib.c
++++ b/libbb/appletlib.c
+@@ -474,6 +474,121 @@ static inline void parse_config_file(void)
+ }
+ # endif /* FEATURE_SUID_CONFIG */
+
++/* We do not want to allow all characters in environment variables.
++ * Function based on patch by Tito.
++ * http://lists.busybox.net/pipermail/busybox/2011-August/076364.html */
++static bool bad_env_var(const char *name)
++{
++ const char *s = name;
++
++ do {
++ /* We don't use isalnum as it will allow locale-specific non-ASCII */
++ /* letters in legacy 8-bit locales. */
++ if (((*name >= 48 && *name <= 57) && name != s) /* no numeric values as first char */
++ || *name == '_' /* allow underscores */
++ || (*name >= 65 && *name <= 90) /* allow A-Z */
++ || (*name >= 97 && *name <= 122) /* allow a-z */
++ ) {
++ continue;
++ }
++ return true;
++ } while (*++name);
++ return false;
++}
++
++static void load_env_vars(void)
++{
++ /* Don't depend on the tools to combine strings. */
++ static const char config_file[] ALIGN1 = "/etc/environment";
++
++ FILE *f;
++ const char *errmsg;
++ unsigned lc;
++ struct stat st;
++
++ if ((stat(config_file, &st) != 0) /* No config file? */
++ || !S_ISREG(st.st_mode) /* Not a regular file? */
++ || (st.st_uid != 0) /* Not owned by root? */
++ || (st.st_mode & (S_IWGRP | S_IWOTH)) /* Writable by non-root? */
++ || !(f = fopen_for_read(config_file)) /* Cannot open? */
++ ) {
++ return;
++ }
++
++ lc = 0;
++
++ while (1) {
++ char buffer[256];
++ char *key;
++ char *val;
++ char *e;
++
++ if (!fgets(buffer, sizeof(buffer), f)) { /* Are we done? */
++ fclose(f);
++ return;
++ }
++
++ key = buffer;
++ lc++; /* Got a (partial) line. */
++
++ /* If a line is too long for our buffer, we consider it an error.
++ * The following test does mistreat one corner case though.
++ * If the final line of the file does not end with a newline and
++ * yet exactly fills the buffer, it will be treated as too long
++ * even though there isn't really a problem. But it isn't really
++ * worth adding code to deal with such an unlikely situation, and
++ * we do err on the side of caution. Besides, the line would be
++ * too long if it did end with a newline. */
++ if (!strchr(key, '\n') && !feof(f)) {
++ errmsg = "line too long";
++ goto pe_label;
++ }
++
++ /* Trim leading and trailing whitespace, ignoring comments, and
++ * check if the resulting string is empty. */
++ key = get_trimmed_slice(key, strchrnul(key, '#'));
++ if (!*key) {
++ continue;
++ }
++
++ /* Get the key */
++ e = strchr(key, '=');
++
++ if (e) {
++ key = get_trimmed_slice(key, e);
++ }
++
++ if (!e || !*key) { /* Missing '=' or empty key. */
++ errmsg = "keyword";
++ goto pe_label;
++ }
++ if (bad_env_var(key)) { /* Check for illegal characters */
++ errmsg = "illegal character";
++ goto pe_label;
++ }
++
++ /* Get the value */
++ val = skip_whitespace(e+1); /* What's after the equal sign? */
++
++ if (!*val) { /* Empty value */
++ errmsg = "value";
++ goto pe_label;
++ }
++ if (*val == '"' && val[(strlen(val)-1)] == '"') {
++ /* We do not want to pass quoted strings to setenv. */
++ val++;
++ val[strlen(val)-1] = 0;
++ }
++
++ if (!getenv(key)) /* User vars > config vars */
++ xsetenv(key, val);
++ continue;
++ } /* while (1) */
++
++ pe_label:
++ fclose(f);
++ bb_error_msg("parse error in %s, line %u: %s", config_file, lc, errmsg);
++}
+
+ # if ENABLE_FEATURE_SUID
+ static void check_suid(int applet_no)
+@@ -802,9 +917,11 @@ int main(int argc UNUSED_PARAM, char **argv)
+ }
+ /* applet_names in this case is just "applet\0\0" */
+ lbb_prepare(applet_names IF_FEATURE_INDIVIDUAL(, argv));
++ load_env_vars();
+ return SINGLE_APPLET_MAIN(argc, argv);
+ #else
+ lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv));
++ load_env_vars();
+
+ applet_name = argv[0];
+ if (applet_name[0] == '-')
+--
+1.7.8
+