COMMAND setlocale() SYSTEMS AFFECTED FreeBSD 2.1.x, 2.2 (prior to December 1996) PROBLEM Thomas H. Ptacek reported that anyone who installed FreeBSD 2.2 prior to December of 1996 is vulnerable to locale routine problems similar to the one that afflicts crt0 start() in FreeBSD 2.1.x (take a look at crt0 bug on this page). Specifically, You are able to cause a shell to be executed from any program that calls setlocale() in FreeBSD 2.2. Thomas tested this out with dmesg, which promptly gave him an SGID "kmem" shell. Note that programs that shed privilege using saved-set UIDs are vulnerable to this problem as well, as the machine code used to take over the affected programs can easily restore privilege. The setlocale() call contains a number of potential exploits through string overflows during environment variable expansion. Because the 2.1.6 and earlier versions of FreeBSD called setlocale() in the C runtime code, the problem is especially acute there in that it essentially effects all binaries on the system. In FreeBSD 2.2 BETA and later releases, the setlocale() call was removed from crt0.c and the exploit closed through additional checks. The setlocale() library function looks for the environment variable "PATH_LOCALE" in the current process's environment, and if it exists, later copies the contents of this variable to a stack buffer without doing proper bounds checking. If the environment variable was specially initialized with the proper amount and type of data prior to running a setuid program, it is possible to cause the program to overflow its stack and execute arbitrary code which could allow the user to become root. Any binary linked on a system with setlocale() built into crt0.c or which calls setlocale() directly has the buffer overrun vulnerability. If this binary has the setuid or setgid bits set, or is called by another setuid/setgid binary (even if that other setuid/setgid binary does not have this vulnerability), unauthorized access may be allowed. SOLUTION The locale routines were patched at the end of 1996 to cause PATH_LOCALE (the environment variable who's contents are trampling all over the stack frames of locale routines) to be ignored if the euid doesn't match the uid; the patch also avoids the stack overrun by allocating space for the variable on the heap with strdup(). People running FreeBSD revisions that don't have this patch will want to make sure they've applied these patches as soon as possible. Vulnerability can easily be assessed by setting LC_CTYPE, filling PATH_LOCALE with 2000 random characters, and attempting to run /sbin/dmesg (which will segfault if the problem exists). FreeBSD recommends recompiling libc with the following patches and then recompiling all staticly linked binaries (all in /sbin and /bin as well as chflags, gunzip, gzcat, gzip, ld, tar and zcat in /usr/bin) eliminates this vulnerability in FreeBSD 2.1.6 and earlier releases: However, a full solution may require a re-link of all setuid/setgid local binaries or all local binaries likely to be called from another setuid/setgid program that were originally linked statically under one of the affected OSs. Dynamically linked executables will benefit directly from this patch once libc is rebuilt and reinstalled and do not need to be relinked. Because of the severity of this security hole, a full update release for FreeBSD 2.1.6 will also be released very shortly, that release being provisionally assigned the version number of 2.1.7. Patch for this can be found at following address: ftp://freebsd.org/pub/CERT/patches/SA-97:01/