COMMAND

    /lib/libterm/tgoto.c

SYSTEMS AFFECTED

    FreeBSD, NetBSD

PROBLEM

    The termcap libraries tgoto function has buffer overflow bug  that
    can be used to overwrite data in BSS segment.  The following  info
    is by kivinen@ssh.fi

    The tgoto have function have static char result[MAXRETURNSIZE] (64
    characters) buffer that is used to return cursor addressing string
    from  tgoto  function.  If  the  CM-cabability  have  more than 64
    characters in it  the tgoto function  will overwrite something  in
    the bss segment after  result-variable. There are no  checks about
    the length  of cm  string nor  checks if  the resulting  string is
    longer than MAXRETURNSIZE characters.

    For example  suid root  system utility  "systat" is  vulnerable to
    this bug. No known exploits of this exists yet, but someone  might
    find such.  Also lots  of systems  have other  suid root/kmem  etc
    program installed  that are  vulnerable to  this bug.  For example
    top and monitor are such programs.

    Easiest way to demonstrate  this is to change  TERMCAP environment
    variable and  add some  about 80  characters to  cm-capablitie and
    then start anything that uses curses or termcap directly  (initscr
    in curses library will call  setterm that will call tgoto  to test
    if we can move cursor around...).

    The fix in netbsd  current that changes the  strcpy at the end  of
    tgoto-function to strncpy isn't sufficient, because the dp pointer
    might  already  be  way  over  the  length  of  result buffer thus
    "sizeof(result) - (dp - result) - 1" results to negative value.

    Notice  that  fix  in  netbsd-current  also  may  return  non null
    terminated string, thus causing unexptected behavior later.

    How-To-Repeat:

~> TERMCAP='xterm|vs100|xterm terminal emulator (X11R6 Window System):
        :am:km:mi:ms:xn:xo:     :co#80:it#8:li#25:
        :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:
        :LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:ae=^O:al=\E[L:as=^N:

:bl=^G:cd=\E[J:ce=\E[K:cl=\E[H\E[2J:cm=\E[%i%d;%dHsakdjaskjdaslkjdlaksj
dlkjdslkjdakljdakljdlalkjasdlkjasdlkjasdlkaslkdaslkjdlksjadkljasdjklasdjklasdlk
jaskld:
        :cr=^M:cs=\E[%i%d;%dr:ct=\E[3k:dc=\E[P:dl=\E[M:do=^J:
        :ei=\E[4l:ho=\E[H:ic=\E[@:im=\E[4h:
        :is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;3;4;6l\E[4l:
        :k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:
        :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:kI=\E[2~:
        :kN=\E[6~:kP=\E[5~:kb=^H:kd=\EOB:ke=\E[?1l\E>:
        :kh=\E[@:kl=\EOD:kr=\EOC:ks=\E[?1h\E=:ku=\EOA:le=^H:
        :md=\E[1m:me=\E[m:mr=\E[7m:nd=\E[C:rc=\E8:sc=\E7:
        :se=\E[m:sf=^J:so=\E[7m:sr=\EM:ta=^I:   :ue=\E[m:up=\E[A:
        :us=\E[4m:'
~> export TERMCAP
~> systat
zsh: 27863 bus error  systat
~>

SOLUTION

    Add check that result buffer isn't overflown.
    This is now fixed in FreeBSD - RELENG_2_1_0, RELENG_2_2, and HEAD.