From 2fea00f846504e7d3a9e2eb0b40903bda91bb3e6 Mon Sep 17 00:00:00 2001 From: Dennis Groenen Date: Thu, 12 Jan 2012 21:19:17 +0100 Subject: [PATCH] appletlib: parse /etc/environment prior to applet launch --- ...arse-etc-environment-prior-to-applet-laun.patch | 150 ++++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 151 insertions(+) create mode 100644 debian/patches/0001-appletlib-parse-etc-environment-prior-to-applet-laun.patch diff --git a/debian/patches/0001-appletlib-parse-etc-environment-prior-to-applet-laun.patch b/debian/patches/0001-appletlib-parse-etc-environment-prior-to-applet-laun.patch new file mode 100644 index 0000000..4e446b3 --- /dev/null +++ b/debian/patches/0001-appletlib-parse-etc-environment-prior-to-applet-laun.patch @@ -0,0 +1,150 @@ +From 92c63984fc28ea1bb0939acfcb551f65d7bfddf7 Mon Sep 17 00:00:00 2001 +From: Dennis Groenen +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 + diff --git a/debian/patches/series b/debian/patches/series index 129139b..5d6ee04 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -19,6 +19,7 @@ parse-complete-hostname.patch #New patches as per reported issues by users showkey-default-option.patch ps-accept-and-ignore-missing-options.patch +0001-appletlib-parse-etc-environment-prior-to-applet-laun.patch #Hotfixes hotfixes/busybox-1.19.3-getty.patch -- 1.7.9.5