Index: sys/kern/kern_environment.c =================================================================== --- sys/kern/kern_environment.c +++ sys/kern/kern_environment.c @@ -359,11 +359,29 @@ } } +static void +getfreesuffix(char *cp, size_t *n) +{ + size_t len = strlen(cp); + char * ncp; + + ncp = malloc(len + 1 + 4 + 1, M_KENV, M_WAITOK); + memcpy(ncp, cp, len); + for (*n = 1; *n <= 9999; (*n)++) { + sprintf(&ncp[len], "_%zu", *n); + if (!_getenv_dynamic_locked(ncp, NULL)) + break; + } + free(ncp, M_KENV); + if (*n > 9999) + 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 +390,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", @@ -394,18 +418,15 @@ * in the kernel config. */ 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 + 5, 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;