Page MenuHomeFreeBSD

D36187.id109616.diff
No OneTemporary

D36187.id109616.diff

Index: sys/kern/kern_environment.c
===================================================================
--- sys/kern/kern_environment.c
+++ sys/kern/kern_environment.c
@@ -359,11 +359,33 @@
}
}
+/* Maximum suffix number appended for duplicate environment variable names. */
+#define MAXSUFFIX 9999
+#define SUFFIXLEN strlen("_" __XSTRING(MAXSUFFIX))
+
+static void
+getfreesuffix(char *cp, size_t *n)
+{
+ size_t len = strlen(cp);
+ char * ncp;
+
+ ncp = malloc(len + SUFFIXLEN + 1, M_KENV, M_WAITOK);
+ memcpy(ncp, cp, len);
+ for (*n = 1; *n <= MAXSUFFIX; (*n)++) {
+ sprintf(&ncp[len], "_%zu", *n);
+ if (!_getenv_dynamic_locked(ncp, NULL))
+ break;
+ }
+ free(ncp, M_KENV);
+ if (*n > MAXSUFFIX)
+ panic("Too many duplicate kernel environment values: %s", cp);
+}
+
static void
init_dynamic_kenv_from(char *init_env, int *curpos)
{
char *cp, *cpnext, *eqpos, *found;
- size_t len;
+ size_t len, n;
int i;
if (init_env && *init_env != '\0') {
@@ -372,6 +394,12 @@
for (cp = init_env; cp != NULL; cp = cpnext) {
cpnext = kernenv_next(cp);
len = strlen(cp) + 1;
+ if (i > KENV_SIZE) {
+ printf(
+ "WARNING: too many kenv strings, ignoring %s\n",
+ cp);
+ goto sanitize;
+ }
if (len > KENV_MNAMELEN + 1 + kenv_mvallen + 1) {
printf(
"WARNING: too long kenv string, ignoring %s\n",
@@ -387,25 +415,31 @@
}
*eqpos = 0;
/*
- * De-dupe the environment as we go. We don't add the
- * duplicated assignments because config(8) will flip
- * the order of the static environment around to make
- * kernel processing match the order of specification
- * in the kernel config.
+ * Handle duplicates in the environment as we go; we
+ * add the duplicated assignments with _N suffixes.
+ * This ensures that (a) if a variable is set in the
+ * static environment and in the "loader" environement
+ * provided by MD code, the value from the loader will
+ * have the expected variable name and the value from
+ * the static environment will have the suffix; and (b)
+ * if the "loader" environment has the same variable
+ * set multiple times (as is possible with values being
+ * passed via the kernel "command line") the extra
+ * values are visible to code which knows where to look
+ * for them.
*/
found = _getenv_dynamic_locked(cp, NULL);
- *eqpos = '=';
- if (found != NULL)
- goto sanitize;
- if (i > KENV_SIZE) {
- printf(
- "WARNING: too many kenv strings, ignoring %s\n",
- cp);
- goto sanitize;
+ if (found != NULL) {
+ getfreesuffix(cp, &n);
+ kenvp[i] = malloc(len + SUFFIXLEN,
+ M_KENV, M_WAITOK);
+ sprintf(kenvp[i++], "%s_%zu=%s", cp, n,
+ &eqpos[1]);
+ } else {
+ kenvp[i] = malloc(len, M_KENV, M_WAITOK);
+ *eqpos = '=';
+ strcpy(kenvp[i++], cp);
}
-
- kenvp[i] = malloc(len, M_KENV, M_WAITOK);
- strcpy(kenvp[i++], cp);
sanitize:
#ifdef PRESERVE_EARLY_KENV
continue;

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 16, 11:49 AM (14 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29769272
Default Alt Text
D36187.id109616.diff (2 KB)

Event Timeline