--- a/sys/kern/kern_environment.c +++ b/sys/kern/kern_environment.c @@ -236,6 +236,16 @@ spin_lock(&kenv_dynlock); cp = kenv_getstring_dynamic(name, NULL); if (cp != NULL) { + /* + * Defense in depth: a dynamic entry can only exceed + * this buffer if it came from the (unvalidated) boot + * environment copy in kenv_init(). Treat oversize + * entries as absent instead of overflowing the stack. + */ + if (strlen(cp) >= sizeof(buf)) { + spin_unlock(&kenv_dynlock); + return (NULL); + } strcpy(buf, cp); spin_unlock(&kenv_dynlock); len = strlen(buf) + 1; @@ -579,6 +589,16 @@ /* copy the static environment to our dynamic environment */ for (i = 0, cp = kern_envp; cp != NULL; cp = kernenv_next(cp)) { len = strlen(cp) + 1; + /* + * Enforce the same per-entry limits as ksetenv(9), so the + * fixed-size buffer in kgetenv(9) can never be overflowed + * by a bootloader-supplied string. + */ + if (len > KENV_MNAMELEN + KENV_MVALLEN) { + kprintf("WARNING: kenv: oversize entry (%d bytes), " + "ignoring string %s\n", len, cp); + continue; + } if (i < (KENV_DYNMAXNUM - 1)) { kenv_dynp[i] = kmalloc(len, M_KENV, M_WAITOK); strcpy(kenv_dynp[i++], cp);