Bugtraq mailing list archives

Re: user flags in public temp space (was Re: chflags() [heads up])


From: deraadt () CVS OPENBSD ORG (Theo de Raadt)
Date: Thu, 5 Aug 1999 01:56:47 -0600


revision 1.59
date: 1999/07/30 18:27:47;  author: deraadt;  state: Exp;  lines: +20 -1
do not permit regular users to chflags/fchflags on chr or blk devices --
even if they happen to own them at the moment.

Mike Frantzen (frantzen () expert cc purdue edu), Kevin Kadow
(kadokev () msg net), and I were discussing the implications of the above
revision to vfs_syscalls.c and realized it must be that root does not
automatically override user-set flags -- root must first unset the flag.

That is correct.

Mike F. immediately seized on the assumption of many OSes that they can
or will have cleared /tmp (and other temp dirs) while in single-user
mode during the boot sequence.  Thus, where there was no /tmp race
before, there is now a /tmp race that the user will surely win for all
non-volatile /tmp filesystems.

That would count for all writeable directories, which basically comes
down to /tmp, /var/tmp, (the emacs lock directory if we want to
temporarily extend the discussion out of system space...), and any
others that users might generate later on.  Please always remember
that users can generate their own world-writeable directories in a
world-writeable system directory (and this can have further
consequences).

As proof of concept, on an OpenBSD 2.5 system, we set a file in /tmp
"_motd" containing some text designed to frighten your typical sysadmin
and rebooted.  /etc/rc contains something like the following lines on
many BSD4.4-lite-derived systems:

      T=/tmp/_motd
      rm -f $T
      sysctl -n kern.version | sed 1q > $T
      echo "" >> $T
      sed '1,/^$/d' < /etc/motd >> $T
      cmp -s $T /etc/motd || cp $T /etc/motd
      rm -f $T

This problem was actually fixed earlier on today, after it was pointed
out by Hugh Graham a few days ago:

revision 1.102
date: 1999/08/04 17:07:27;  author: millert;  state: Exp;  lines: +9 -8
Use mktemp(1) for motd /tmp file during boot.  This fixes a potential
problem noted by hugh () openbsd org whereby a user could create the
well-known /tmp/_motd file and use chflags to make it unremovable.
Then at the next reboot the user's /tmp/_motd would end up in the
system motd.

Sorry, you but weren't first ;-)

Interestingly, in OpenBSD2.5, FreeBSD3.2, and BSDI3.2, motd appears to
be the only file affected in the various rc scripts.

You may want to check their implementations of locate.updatedb(8).  We
found relevant /tmp races in there before, as well.

On many systems,
however, admins will have added programs that will rely on /tmp being
clear[able] before a user could possibly run a function (through cron,
at, logging in, etc.) and the results will be more than cosmetic.

On a related note, we've been very careful to split the typical
/etc/rc.local into /etc/rc.local and /etc/rc.securelevel.  The
rc.securelevel script is run early on from rc (before the system goes
secure) and it does things which require the system to be in
"insecure" mode.  The system is then forced into secure mode, so that
the remainder of rc can run with some securelevel constraints.  As a
side effect, this also permits us to run rc.local quite a bit later on
during the run, which is convenient.  It makes a number of problems
harder to tickle, such as sendmail .forward files, cron @reboot jobs,
and such.

Possible long-term fixes we've theo-rized:

A strange pun.

a) Root should not use /tmp.  Root is root and, as the proverbial
800-pound gorilla, can make temporary files wherever it pleases.
FreeBSD, for example, seems to be doing a lot in /var/run, which is
root-owned, and not world-writable.  At least root should use
subdirectories of /tmp and test to see if it can mkdir(1) them before use
(see OpenBSD2.5's /etc/security, for example).

As much as possible, we've now killed almost all of the /tmp races in
the system, so root is as safe as any other user.  Even gcc now plays
things safe, it appears.  But /tmp problems keep occuring in packages
which people add to the system.

When I have attempted to make developer's of faulty packages aware of
needed repairs to their software, I've typically found them to be
rather unreceptive; most people just do not consider this is a big
deal.  Many of these fixes are very easy, if people would just read
our updated man pages on the topic.  However, some programs require
clever tricks or severe redesigning to get these problems fixed.  Go
look at lynx sometime, it's probably the worst mis-user of /tmp
around.

The man pages in question are:

        http://www.openbsd.org/cgi-bin/man.cgi?query=mkstemp&format=html
        http://www.openbsd.org/cgi-bin/man.cgi?query=mktemp&format=html 

Go check them out... we're trying to teach people.

b) In rm(1), make the -f option clear user flags when rm -f is called
by root (not a bad workaround).

Hugh recommended the same.  Considering the find /tmp stuff that
happens in /etc/rc, I have been giving thought to adding a -F flag
which would do that.  Unfortunately, from a system perspective, this
is gross too.

Please also note that the fts(3) and ftw(3) routines that a lot of
systems use for recursive directory traverals, are not safe on
writeable directories on the way; these could feasably be replaced
with symbolic links by an attacker to make programs like rm -rf and
find do completely the wrong thing.  Todd Miller spent a lot of time
reworking our fts(3) implementation to avoid that issue.  And of
course find on most systems has other similar races.

c) Make root automatically override user-set flags (possibly will
create other complications for user-land programs relying on root
passing over such files).  This would be akin to Solaris 2.51 and 2.6's
ACLs.

This should also probably be looked into a bit more, but currently I
am leaning away from this being right.  It's a rather large change to
the way flags work.  Do we also then make dump not honour user
nodump.. oh, wait, dump is run by root.... no, that would not make
sense, would it.  So it becomes somewhat inconsistant.  To some
degree, securelevels are trying to make root more equal to users.

d) Modify vfs_syscalls.c to disallow user-set flags on files in
directories the user does not own.

This cannot work.  The user simply links the file into his own
directory, sets the flag on the file, and deletes his link.  You've
forgotten about the directory-entry vs. inode split that Unix has in
it's filesystem.

Our guess is that all 4.4-lite derived BSDs that have not explicitly
disallowed regular users to chflags/fchflags on character or block
devices will be vulnerable.

Absolutely.


Current thread: