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:
- user flags in public temp space (was Re: chflags() [heads up]) Strange (Aug 04)
- Re: user flags in public temp space (was Re: chflags() [heads up]) Brett Lymn (Aug 05)
- Re: user flags in public temp space (was Re: chflags() [heads up]) Jason Bratton (Aug 05)
- Re: user flags in public temp space (was Re: chflags() [heads up]) Theo de Raadt (Aug 05)
- Re: user flags in public temp space (was Re: chflags() [heads up]) Andrew Brown (Aug 05)
- Re: user flags in public temp space (was Re: chflags() [heads up]) Darren Reed (Aug 05)
- Re: user flags in public temp space (was Re: chflags() [heads up]) Theo de Raadt (Aug 06)
- Re: user flags in public temp space (was Re: chflags() [heads up]) Darren Reed (Aug 06)
- Re: user flags in public temp space (was Re: chflags() [heads up]) Tim Fletcher (Aug 06)
- Re: user flags in public temp space (was Re: chflags() [heads up]) Darren Reed (Aug 07)
- Re: user flags in public temp space (was Re: chflags() [heads up]) Doug Harple (Aug 09)
- Re: user flags in public temp space (was Re: chflags() [heads up]) Brett Lymn (Aug 05)
- Re: user flags in public temp space (was Re: chflags() [heads up Adam Morris (Aug 09)
- Re: user flags in public temp space (was Re: chflags() [heads up James E. Pace (Aug 10)
- New cfingerd 1.4.0 - Configurable Finger Daemon Martin Schulze (Aug 10)
