COMMAND
libmytinfo (ncurses)
SYSTEMS AFFECTED
FreeBSD 3.x before 2000-04-25
PROBLEM
Following is based on FreeBSD Security Advisory. libmytinfo is
part of ncurses, a text-mode display library. libmytinfo allows
users to specify an alternate termcap file or entry via the
TERMCAP environment variable, however this is not handled
securely and contains a overflowable buffer inside the library.
This is a security vulnerability for binaries which are linked
against libmytinfo and which are setuid or setgid (i.e. run with
elevated privileges). It may also be a vulnerability in other
more obscure situations where a user can exert control over the
environment with which an ncurses binary is run by another user.
FreeBSD 3.x and earlier versions use a very old, customized
version of ncurses which is difficult to update without breaking
backwards-compatibility. The update was made for FreeBSD 4.0,
but it is unlikely that 3.x will be updated. However, the ncurses
source is currently being audited for further vulnerabilities.
Certain setuid/setgid third-party software (including FreeBSD
ports/packages) may be vulnerable to a local exploit yielding
privileged resources, such as network sockets, privileged
filesystem access, or outright privileged shell access (including
root access). FreeBSD 4.0 and above are NOT vulnerable to this
problem.
SOLUTION
Remove any setuid or setgid binary which is linked against
libmytinfo (including statically linked), or remove set[ug]id
privileges from the file as appropriate. The following
instructions will identify the binaries installed on the system
which are candidates for removal or removal of file permissions.
Since there may be other as yet undiscovered vulnerabilities in
libmytinfo it may be wise to perform this audit regardless of
whether or not you upgrade your system as described below. In
particular, see the note regarding static linking below.
Of course, it is possible that some of the identified files may be
required for the correct operation of your local system, in which
case there is no clear workaround except for limiting the set of
users who may run the binaries, by an appropriate use of user
groups and removing the "o+x" file permission bit.
1) Download the 'libfind.sh' script from
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-00:17/libfind.sh
2) Verify the md5 checksum and compare to the value below:
# /sbin/md5 libfind.sh
MD5 (libfind.sh) = 59dceaa76d6440c58471354a10a8fb0b
3) Run the libfind script against your system:
# sh libfind.sh /
This will scan your entire system for setuid or setgid
binaries which are linked against libmytinfo. Each returned
binary should be examined (e.g. with 'ls -l' and/or other
tools) to determine what security risk it poses to your
local environment, e.g. whether it can be run by arbitrary
local users who may be able to exploit it to gain
privileges.
4) Remove the binaries, or reduce their file permissions, as
appropriate.
Solution is to upgrade your FreeBSD 3.x system to 3.4-STABLE
after the correction date, or patch your present system source
code and rebuild. Then run the libfind script as instructed above
and identify any statically-linked binaries (those reported as
"STATIC" by the libfind script). These should either be removed,
recompiled, or have privileges restricted to secure them against
this vulnerability (since statically-linked binaries will not
be affected by recompiling the shared libmytinfo library).
To patch your present system: save the patch below into a file,
and execute the following commands as root:
cd /usr/src/lib/libmytinfo
patch < /path/to/patch/file
make all
make install
Patches for 3.x systems before the resolution date:
Index: findterm.c
===================================================================
RCS file: /usr/cvs/src/lib/libmytinfo/Attic/findterm.c,v
retrieving revision 1.3
diff -u -r1.3 findterm.c
--- findterm.c 1997/08/13 01:21:36 1.3
+++ findterm.c 2000/04/25 16:58:19
@@ -242,7 +242,7 @@
} else {
s = path->file;
d = buf;
- while(*s != '\0' && *s != ':')
+ while(*s != '\0' && *s != ':' && d - buf < MAX_LINE - 1)
*d++ = *s++;
*d = '\0';
if (_tmatch(buf, name)) {
@@ -259,7 +259,7 @@
} else {
s = path->file;
d = buf;
- while(*s != '\0' && *s != ',')
+ while(*s != '\0' && *s != ',' && d - buf < MAX_LINE - 1)
*d++ = *s++;
*d = '\0';
if (_tmatch(buf, name)) {