Bugtraq mailing list archives
setlocale() bug in all released versions of FreeBSD (SA-97:01)
From: aleph1 () DFW NET (Aleph One)
Date: Thu, 6 Feb 1997 17:59:11 -0600
============================================================================= FreeBSD-SA-97:01 Security Advisory Revised: Wed Feb 05 09:58:56 PDT 1997 FreeBSD, Inc. Topic: setlocale() bug in all released versions of FreeBSD Category: core Module: libc Announced: 1997-02-05 Affects: FreeBSD 2.1.6 and earlier systems suffer from this vulnerability for all binaries due to setlocale() being called from crt0.o. Corrected: 1997-02-05 -stable, 1996-11-27 -current and RELENG_2_2 sources Source: FreeBSD specific bug FreeBSD only: unknown Patches: ftp://freebsd.org/pub/CERT/patches/SA-97:01/ ============================================================================= I. Background 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. There has also been some confusion over the implications of loading locale data by privileged programs. The facility for a user to supply their own (possibly corrupt or abused) locale data to non-privileged processes was removed in all releases on 1997-02-04. This was originally a debugging facility that got little use and the user can now only direct system binaries to load system administrator sanctioned locale files. This problem is present in all source code and binary distributions of FreeBSD released on or before 1996-11-27. II. Problem Description 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. III. Impact Any binary linked on a system with setlocale() built into crt0.c (see list of affected releases in section I above) 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. IV. Solution(s) 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. Index: lib/libc/locale/collate.c =================================================================== RCS file: /home/ncvs/src/lib/libc/locale/collate.c,v retrieving revision 1.4.4.2 diff -c -r1.4.4.2 collate.c *** collate.c 1996/06/05 02:47:55 1.4.4.2 --- collate.c 1997/02/05 10:21:59 *************** *** 64,70 **** __collate_load_error = 1; if (!encoding) return -1; ! if (!path_locale && !(path_locale = getenv("PATH_LOCALE"))) path_locale = _PATH_LOCALE; strcpy(buf, path_locale); strcat(buf, "/"); --- 64,70 ---- __collate_load_error = 1; if (!encoding) return -1; ! if (!path_locale) path_locale = _PATH_LOCALE; strcpy(buf, path_locale); strcat(buf, "/"); Index: lib/libc/locale/rune.c =================================================================== RCS file: /home/ncvs/src/lib/libc/locale/rune.c,v retrieving revision 1.2.6.3 diff -c -r1.2.6.3 rune.c *** rune.c 1996/06/05 02:47:59 1.2.6.3 --- rune.c 1997/02/05 10:22:00 *************** *** 71,77 **** return(0); } ! if (!PathLocale && !(PathLocale = getenv("PATH_LOCALE"))) PathLocale = _PATH_LOCALE; (void) strcpy(name, PathLocale); --- 71,77 ---- return(0); } ! if (!PathLocale) PathLocale = _PATH_LOCALE; (void) strcpy(name, PathLocale); Index: lib/libc/locale/setlocale.c =================================================================== RCS file: /home/ncvs/src/lib/libc/locale/setlocale.c,v retrieving revision 1.3.4.2.2.1 diff -c -r1.3.4.2.2.1 setlocale.c *** setlocale.c 1996/06/05 02:48:03 1.3.4.2.2.1 --- setlocale.c 1997/02/05 10:22:00 *************** *** 58,64 **** int found, i, len; char *env, *r; ! if (!PathLocale && !(PathLocale = getenv("PATH_LOCALE"))) PathLocale = _PATH_LOCALE; if (category < 0 || category >= _LC_LAST) --- 58,64 ---- int found, i, len; char *env, *r; ! if (!PathLocale) PathLocale = _PATH_LOCALE; if (category < 0 || category >= _LC_LAST) Index: lib/libc/locale/startup_setlocale.c =================================================================== RCS file: /home/ncvs/src/lib/libc/locale/Attic/startup_setlocale.c,v retrieving revision 1.2.4.2 diff -c -r1.2.4.2 startup_setlocale.c *** startup_setlocale.c 1995/08/28 05:06:50 1.2.4.2 --- startup_setlocale.c 1997/02/05 10:22:00 *************** *** 23,29 **** int found, i, len; char *env, *r; ! if (!PathLocale && !(PathLocale = getenv("PATH_LOCALE"))) PathLocale = _PATH_LOCALE; if (category < 0 || category >= _LC_LAST) --- 23,29 ---- int found, i, len; char *env, *r; ! if (!PathLocale) PathLocale = _PATH_LOCALE; if (category < 0 || category >= _LC_LAST) ============================================================================= FreeBSD, Inc. Web Site: http://www.freebsd.org/ Confidential contacts: security-officer () freebsd org PGP Key: ftp://freebsd.org/pub/CERT/public_key.asc Security notifications: security-notifications () freebsd org Security public discussion: security () freebsd org Notice: Any patches in this document may not apply cleanly due to modifications caused by digital signature or mailer software. Please reference the URL listed at the top of this document for original copies of all patches if necessary. =============================================================================
Current thread:
- [linux-security] Linux virus Aleph One (Feb 04)
- Re: [linux-security] Linux virus Jim Dennis (Feb 05)
- Re: [linux-security] Re: Linux virus Alan Cox (Feb 05)
- Re: [linux-security] Re: Linux virus Leejay Wu (Feb 05)
- bliss version 0.4.0 nobody () INTERNIC NET (Feb 05)
- HPSBUX9702-052 Security Vulnerability in the rlogin executable Aleph One (Feb 05)
- [linux-security] Re: Linux virus Aleph One (Feb 06)
- setlocale() bug in all released versions of FreeBSD (SA-97:01) Aleph One (Feb 06)
- Wierd behavior of MS's NT4 DNS Jason T. Luttgens (Feb 07)
- New OFFICIAL patch for BSD/OS 2.1 (*SECURITY*) (fwd) Josh Gilliam (Feb 07)
- Bliss: The Facts Jared Mauch (Feb 08)
- view-source myst (Feb 08)
- IRIX: Bug in startmidi David Hedley (Feb 09)
- Re: IRIX: Bug in startmidi Nafees Bin Zafar (Feb 09)
- Security Advisory: A simple TCP spoofing attack Oliver Friedrichs (Feb 09)
- Re: Security Advisory: A simple TCP spoofing attack Wietse Venema (Feb 12)
- buffer overflow in configurable fingerd? M Shariful Anam (Feb 12)
- Re: buffer overflow in configurable fingerd? Ken Hollis (Feb 12)
- Re: [linux-security] Linux virus Jim Dennis (Feb 05)