Subject: lib/24384: Undocumented termcap-feature considered harmful
To: None <>
From: Christian Biere <>
List: netbsd-bugs
Date: 02/10/2004 21:42:07
>Number:         24384
>Category:       lib
>Synopsis:       Undocumented termcap-feature considered harmful
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    lib-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Feb 10 21:43:00 UTC 2004
>Originator:     Christian Biere
>Release:        NetBSD 1.6ZH
System: NetBSD cyclonus 1.6ZH NetBSD 1.6ZH (STARSCREAM) #0: Fri Feb 6 00:16:58 CET 2004 root@cyclonus:/usr/src/sys/arch/i386/compile/STARSCREAM i386

tgetent() and t_getent() inspect the environment variables TERMCAP and
TERMPATH. If TERMPATH isn't set it is automagically assumed to be
"${HOME+$HOME/}.termcap:/usr/share/misc/.termcap". So if HOME isn't set
the .termcap (or .termcap.db) in the current working directory will be
used. The latter is usually the case in single-user mode. This means
if you enter a directory which contains .termcap or .termcap.db any
program which uses termcap and actually tgetent() started from there
might at least cause a hang, out-of-memory crash, weird terminal
behaviour. Even worse, termcap has some properties which take pathnames
as arguments. So, an attacker might put an .termcap into a directory
with the property pointing to /etc/master.passwd or some really
interesting file and the termcap using program will read the file
into memory so that a coredump would contain the content.

I assume the necessary circumstances to actually exploit this are very
unlikely, harmless abuse by a joker might be a little more likely.
Anyway, I find this feature useless and annoying because it's not
documented. I guess it's really inspired by single-user in which
HOME isn't set and you're usually *starting* in /.

[Maybe it *would* be a good idea to use O_NONBLOCK for dbopen() in
 cgetent() and allow only regular files. That would prevent at least
 some kind of abuses.]


$ unset HOME
$ ln -s /dev/zero .termcap
$ ln -s /dev/zero .termcap.db
$ man less


Using getpwent()->pw_dir would be a much more useful feature, IMHO.
Using / instead of $PWD would be OK, too because it's unlikely anyone
can place a .termcap{,.db} there if he isn't supposed to. Documentation
is a must due to POLA.