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.