copyright | disclaimer | privacy | contact  
Australia's Leading Computer Emergency Response Team
 
Search this site

 
On this site

 > HOME
 > About AusCERT
 > Membership
 > Contact Us
 > PKI Services
 > Training
 > Publications
 > Sec. Bulletins
 > Conferences
 > News & Media
 > Services
 > Web Log
 > Site Map
 > Site Help
 > Member login





 

ESB-97.018 -- FreeBSD Advisory on setlocale()

Date: 05 February 1997

Click here for printable version
Click here for PGP verifiable version
-----BEGIN PGP SIGNED MESSAGE-----

===========================================================================
              AUSCERT External Security Bulletin Redistribution

                             
                ESB-97.018 -- FreeBSD Advisory on setlocale()
                               5 February 1997

===========================================================================

FreeBSD Inc. has released the following advisory concerning a vulnerability
in the setlocale() routine under all released versions of FreeBSD.  This
vulnerablility may allow unauthorised access.

If you believe that your system has been compromised, contact AUSCERT or your
representative in FIRST (Forum of Incident Response and Security Teams).

Internet Email: auscert@auscert.org.au
Facsimile:      (07) 3365 4477
Telephone:      (07) 3365 4417 (International: +61 7 3365 4417)
	AUSCERT personnel answer during Queensland business hours
	which are GMT+10:00 (AEST).
	On call after hours for emergencies.


- --------------------------BEGIN INCLUDED TEXT--------------------

=============================================================================
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.
=============================================================================


- --------------------------END INCLUDED TEXT--------------------

-----BEGIN PGP SIGNATURE-----
Version: 2.6.3i
Charset: noconv
Comment: ftp://ftp.auscert.org.au/pub/auscert/AUSCERT_PGP.key

iQCVAwUBPMV4eyh9+71yA2DNAQGx+wP/UoSvLKTI3MIY8TPB8I0CcDMdiC7JJZR+
cuXgBON1PqPNc51uJK95FhGOep0MEc4H0BgquGGISuEoSktKg4EqmMilc9eEw0S1
0QSPilbHoBG3IEf6W+C2jrLcuS88IcP9Hlt4Op0pCp1DcKIIg57BNbXpL2CspILw
Cb3FcY2k0qc=
=RDxg
-----END PGP SIGNATURE-----