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/