Subject: NetBSD Security Advisory 2002-012: buffer overrun in setlocale
To: None <tech-security@netbsd.org, current-users@netbsd.org>
From: NetBSD Security Officer <security-officer@netbsd.org>
List: current-users
Date: 09/17/2002 12:26:14
-----BEGIN PGP SIGNED MESSAGE-----


		 NetBSD Security Advisory 2002-012
		 =================================

Topic:		buffer overrun in setlocale

Severity:	local root exploit if X11 (xterm) is installed.

Version:	NetBSD-current:	source prior to August 8, 2002
		NetBSD-1.6 beta:source prior to August 8, 2002
		NetBSD-1.5.3:	affected
		NetBSD-1.5.2:	affected
		NetBSD-1.5.1:	affected
		NetBSD-1.5:	affected
		NetBSD-1.4.*:	affected
		All prior NetBSD releases.

Fixed:		NetBSD-current:		August 8, 2002
		NetBSD-1.6 branch:	August 8, 2002 (1.6 includes the fix)
		NetBSD-1.5 branch:	September 5, 2002
		NetBSD-1.4 branch:	not yet

Abstract
========

There was a boundary checking bug of array suffix in setlocale()
function in libc.  If the setlocale() function is used with arguments
satisfying a specific condition (see below), there is a possibility
that this could be exploitable.  This condition is as the following:

1. setlocale() function is called for LC_ALL category and
2. The string pointed to by the second argument of setlocale contains
   over six elements separated by slash.  An example of string causing
   this problem to setlocale() is "C/C/C/C/C/C/C".  (note that the
   frequently used special form, setlocale(LC_ALL, ""), does not cause
   this problem, since the code having this problem is never executed
   in this case.)
3. To use this bug to exploit, the second argument of setlocale needs
   to be derived from user-given data (e.g. environment variables or
   command line arguments) and the program need to be setuid or
   need to be involved in some setuid program or daemon.

Most programs using Xt, including xterm (setuid program), may satisfy
this condition.  All other programs in NetBSD distribution except for
packages do not satisfy it.  In packages, zsh is one of the most
important program that may satisfy this condition.


Technical Details
=================

The setlocale (or its subcontractor, __setlocale) function, defined in
lib/libc/locale/setlocale.c, is used to change the locale of each
locale category.  setlocale() function switches the locale of the
category specified by the first argument to the second argument.  The
special category LC_ALL can be used to change all locale categories at
the same time.  In this case, the NetBSD implementation of setlocale
allows a special form of the second argument string to specify
individual locales per category.

In this form, each locale is given in a single string separated by
slashes ('/'), as "A/B/C/D/E/F".  Here, each element corresponds to
categories LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME and
LC_MESSAGES, respectively.  The setlocale() function attempts to
decomposit these elements into an array object named new_categories
locally defined in lib/libc/locale/setlocale.c.  However, the code to
check the array boundary was lacking and thus this decomposition code
could destroy data segment if a string having over six elements was
given.

If the program which has set[ug]id bit or which is called from
set[ug]id program calls setlocale() with LC_ALL as the first argument
and with the string derived from user-given data
(e.g. setlocale(LC_ALL, getenv("FOO")) ) as the second argument, then
such program could be exploitable.  DefaultLanguageProc function of X
Toolkit Intrinsics (Xt) is a example of such usage. DefaultLanguageProc 
calls setlocale as "setlocale(LC_ALL, xnl)".  Here, xnl variable is
null string ("") by default, but can be overriden by user via
- -xnllanguage option.  Most Xt programs, including xterm, use this
language procedure.  xterm is a setuid root program and thus any local
user could illegally acquire root account by using this problem.

On the other hand, the frequently used special form,
setlocale(LC_ALL, ""), does not have this problem because the decomposition
code is never executed in this form, although user-given LC_ALL environment
variable is similarly referred.


Solutions and Workarounds
=========================

The recent NetBSD 1.6 release is not vulnerable to this issue. A full
upgrade to NetBSD 1.6 is the recommended resolution for all users able
to do so. Many security-related improvements have been made, and
indeed this release has been delayed several times in order to include
fixes for a number of recent issues.

Otherwise, you must update libc.  Also, you must update all statically
linked binaries satisfying the condition above - although the NetBSD
distribution contains no such static binaries, you may have some from
pkgsrc packages or local programs.  The following instructions
describe how to update libc.


* NetBSD-current:

	Systems running NetBSD-current dated from before 2002-08-08
	should be upgraded to NetBSD-current dated 2002-08-08 or later.

	The following directories need to be updated from the
	netbsd-current CVS branch (aka HEAD):
		lib/libc/locale

	To update from CVS, re-build, and re-install libc:
		# cd src
		# cvs update -d -P lib/libc/locale

		# cd lib/libc
		# make cleandir dependall
		# make install


* NetBSD 1.6 betas:

	Systems running NetBSD 1.6 BETAs and Release Candidates should
	be upgraded to the NetBSD 1.6 release.

	If a source-based point upgrade is required, sources from the
	NetBSD 1.6 branch dated 2002-08-08 or later should be used.

	The following directories need to be updated from the
	netbsd-1-6 CVS branch:
		lib/libc/locale

	To update from CVS, re-build, and re-install libc:
		# cd src
		# cvs update -d -P -r netbsd-1-6 lib/libc/locale

		# cd lib/libc
		# make cleandir dependall
		# make install


* NetBSD 1.5.x:

	Systems running NetBSD 1.5 betas dated from before 2002-09-05
	should be upgraded to NetBSD 1.5 tree dated 2002-09-05 or later.

	The following directories need to be updated from the
	netbsd-1-5 CVS branch:
		lib/libc/locale

	To update from CVS, re-build, and re-install libc:
		# cd src
		# cvs update -d -P -r netbsd-1-5 lib/libc/locale

		# cd lib/libc
		# make cleandir dependall
		# make install


* NetBSD 1.4.x:

	not yet


Thanks To
=========

Andrey A. Chernov for initial fix in FreeBSD source.

Takuya SHIOZAKI for preparing the initial advisory text.

The NetBSD Release Engineering teams, for great patience and
assistance in dealing with repeated security issues discovered
recently.


Revision History
================

	2002-09-16	Initial release


More Information
================

An up-to-date PGP signed copy of this release will be maintained at
  ftp://ftp.netbsd.org/pub/NetBSD/security/advisories/NetBSD-SA2002-012.txt.asc

Information about NetBSD and NetBSD security can be found at
http://www.NetBSD.ORG/ and http://www.NetBSD.ORG/Security/.


Copyright 2002, The NetBSD Foundation, Inc.  All Rights Reserved.

$NetBSD: NetBSD-SA2002-012.txt,v 1.11 2002/09/16 05:17:55 dan Exp $


-----BEGIN PGP SIGNATURE-----
Version: 2.6.3ia
Charset: noconv

iQCVAwUBPYVqPT5Ru2/4N2IFAQF2ngP9Gy/ZVH4yizEHSiv8f1OLHxn2auf3J/bx
Tit7KQVGiCQS/1sZ2UxV8ZVKQOzJwrJNHuJ23YS2iDs//RxghmpjVGQPmS91t7vb
X3z7SEy3mgEe0VClcDMSamxiomPi8rcH37CdlflHkTneX/UYsPgLClGT55PXtOu9
ZfqrAQGUgeU=
=5MrG
-----END PGP SIGNATURE-----