Subject: bin/3330: Security bug (buffer overflow) in lib/libterm/tgoto.c
To: None <gnats-bugs@gnats.netbsd.org, FreeBSD-gnats-submit@freebsd.org>
From: None <kivinen@ssh.fi>
List: netbsd-bugs
Date: 03/14/1997 04:43:04
>Number:         3330
>Category:       bin
>Synopsis:       Security bug (buffer overflow) in lib/libterm/tgoto.c
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Mar 13 18:50:01 1997
>Last-Modified:
>Originator:     Tero Kivinen
>Organization:
SSH Communications Security
>Release:        NetBSD 1.2, FreeBSD 2.1-STABLE
>Environment:

System: NetBSD taulu.ssh.fi 1.2 NetBSD 1.2 (TAULU) #50: Mon Feb 24 21:40:52 EET 1997 kivinen@taulu.ssh.fi:/usr/src/sys/arch/i386/compile/TAULU i386
System: FreeBSD pilari.ssh.fi 2.1.5-RELEASE FreeBSD 2.1.5-RELEASE #1: Thu Oct 31 23:58:19 EET 1996     root@lamppu.ssh.fi:/usr/src/sys/compile/SSHGEN  i386

>Description:

The termcap libraries tgoto function has buffer overflow bug that can
be used to overwrite data in BSS segment.

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;%dHsakdjaskjdaslkjdlaksjdlkjdslkjdakljdakljdlalkjasdlkjasdlkjasdlkaslkdaslkjdlksjadkljasdjklasdjklasdlkjaskld:
	: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
~>

>Fix:

Add check that result buffer isn't overflown.
-- 
kivinen@iki.fi		              	     Work : +358-9-4354 3205
Magnus Enckellin kuja 9 K 19, 02610, Espoo   Home : +358-9-502 1573
>Audit-Trail:
>Unformatted: