COMMAND
rm -r
SYSTEMS AFFECTED
most systems
PROBLEM
Morten Welinder found following. If root ever does "rm -rf
/tmp/foo" for a directory structure not completely owned by root,
a local user can delete all files that root can. Such deletions
are common for (a) /tmp cleanup and (b) before creating a specific
directory in /tmp/. Note that the same applies to non-root users.
I.e. if a normal user runs "rm -rf" on a directory to which unsafe
accounts have write permission, they could be tricked into
deleting arbitrary files (from directories on which they have
write permission).
"rm -r" implementations (Solaris 7, Gnu 4.0 checked) walk the
directories, lstats files, and chdirs into directories (and
recurs). Oh, and deletes stuff, of course. It is possible to
replace a directory by a symlink, say "/", and have rm cheerfully
follow it. The race window is small -- it will take thousands
upon thousands of tries. Moreover, since the racing involves
rmdir -- which typically is not very fast -- you'll need patience
and "nice" and any other help you can get.
Also affected are chmod, chown, chgrp (this is guesswork) ... and
every other program that modifies the filesystem in any way,
unless it jumps through the same hoops. If, that is, you let them
near directories with unsafe permissions.
SOLUTION
Use a statically-linked "rm" and "chroot /tmp" first. In the
long term, there are three main options:
1. Abolish symlinks. This might be considered overkill, though.
2. Write every program as if it was a /tmp cleaner. I.e. never
pass full pathnames to system calls, but chdir() down one level
at a time from "/", [lf]stat()ing as you go and never following
symlinks, then open("./filename"). In which case, you may as
well abolish symlinks.
3. Don't do dangerous things in world-writable directories. Better
still, get rid of world-writable directories altogether; it
isn't that difficult. IOW, fix the bug, not the symptoms.
4. Add an option to not traverse symlinks in system calls. Call
realpath() on initial argument before setting.