TUCoPS :: BSD :: bsd156.htm

setlocale() - cause a shell to be executed
1st Jan 1996 [SBWID-156]
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.

	

	

	 Update (18 september 2002)

	 ======

	

	Beleive it or not, but this issue existed until now in NetBSD too.  From
	NetBSD security advisory [2002-012: buffer overrun in setlocale] :
	

	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.

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/

	

	

	

	 NetBSD

	 ======

	

	Updates available, check : http://www.NetBSD.ORG/Security/

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH