[prev in list] [next in list] [prev in thread] [next in thread] 

List:       bugtraq
Subject:    Re: Tired of /tmp? Here's a proposed solution
From:       Zygo Blaxell <zblaxell () myrus ! com>
Date:       1996-08-29 16:23:50
[Download RAW message or body]

Hmmm...before reading this article, try this on your platform.  It's
analogous to that program that tests to see what O_CREAT|O_EXCL does when
the last name in the path is a symlink to a nonexistent file, but it
tests to see if mkdir() fails a similar test.

#!/bin/sh
mkdir empty-directory
ln -s test-directory empty-directory/test-symlink
mkdir empty-directory/test-symlink
if [ -d empty-directory/test-directory ]
then result="does"
else result="does NOT"
fi
echo "mkdir $result follow symlinks on `uname -msr`"

Here's my results:
        mkdir does NOT follow symlinks on Linux 2.0.11 i586
        mkdir does NOT follow symlinks on SunOS 5.3 sun4m


In article <199608281021.LAA00147@elbereth.sophos.com>,
Matthew J Brown  <BUGTRAQ@NETSPACE.ORG> wrote:
>Guido M. Witmond writes:
> > Well, this is a good quick hack. What about removing the CONCEPT of
> > public writable filesystems like /tmp.

It's kind of difficult to do without public-accessible structures
in general, unless you're willing to run a daemon for every possible
operation on shared data.  I'd prefer to fix the problems with the
filesystem.

> > One of the reasons for the /tmp filesystem is to provide users with some
> > extra diskspace that's for temporary use and does not limit users to their
> > respective quotas.
> > Nowadays with ever larger and cheaper disks it is acceptable to let every
> > user create a ~/tmp directory as a private scrapyard. This prevents any
> > /tmp attacks and the use of the quota-system gives enough flexibility
> > to enlarge or reduce the area, even more than the fixed size of /tmp.

>/tmp still has many advantages, though.
>
>Firstly, it's pretty much guaranteed to be a local filesystem, and not
>on an NFS partition.  This gives better performance.  On some systems
>it's a tmpfs partition, with the advantage of even better performance
>and automatic deletion on reboot.
[...]
>I think what is actually needed is to have a directory /tmp/<user> for
>each user on the system.  This keeps advantages one and two: it's a
>local disk and automatically deleted.  This directory should be owned
>by the user and mode 700.

Set up each user such that ~user/tmp is a symlink to /tmp/<user>.  This
has the side benefit of allowing users to choose which partition they want
to have as their "default" temporary space (or admins to choose for them).

This is not going to get standardized or accepted very soon: it's too
late to even propose that everyone use mktemp() or tmpnam() now, let
alone having to use some new user database service to find out where to
put temporary files.

Just imagine examining, patching, and testing the source code of even 10%
of the executables on your system.  Then consider that most Unix flavors
have /tmp-related race condition bugs in between 5 and 30% of their
standard system binaries.  Most vendor application software is even worse
(closer to 80% in my relatively limited experience).  Even worse, vendor
applications like to create their own world-writable directories other
than /tmp.

Giving up using the string "/tmp" in Unix-compatible software is not
an option.

>Secondly, it's an area that's automatically deleted every so often, so
>has a different 'feel' to it than a ~/tmp.

I agree entirely.

Putting temporary files physically on the same partition on /home is just
not a good idea.  Quota management becomes harder, backup performance will
go down the toilet, and there's disk fragmentation, drive I/O and seeking
saturation, and slow disk/NFS performance issues.

Additionally, it doesn't solve race condition problems for some tasks.
An automatic temporary file removal service has to be aware of race
conditions whether everyone can write to temporary directories, or just
the attacker.  Even the B-level-secure system described (with one /tmp
directory per security level, and a special security level that can
access all /tmp directories) is vulnerable to such attacks, unless it
has some other defense I don't know about.

>Thirdly, it's often used to pass files to other users on the same
>system.
[...]
>Then a space ought to be set up for the temporary exchange of files
>between users, called something like /common.  This should also be
>automatically deleted, but programs should not automatically create
>temp files here.

This is an interesting idea; however, strcmp("/common","/tmp") != 0...

I propose to change the behavior of the already-overloaded sticky bit on
/tmp, as follows:

        Current behavior
        0. rename(file,file) and unlink(file) are not permitted if:
                uid(file) != uid(.) and
                uid(file) != effective_uid and
                effective_uid != 0.

        New behavior
        1. link(file,file2) is not permitted under the same conditions as
                rename and unlink, for both source and target.  This means
                you can't do 'ln /etc/passwd /tmp' unless you are root, or
                'ln /tmp/mbox.zblaxell ~zblaxell/.rhosts' unless you are
                root or zblaxell.
        2. any operation following a symlink is not permitted if the symlink
                is not owned by the effective uid, period.  This includes
                root!  root may readlink() the symlink, may rename or unlink
                it (none of which follows the symlink), but may not open
                files or search directories through it.

Condition #2 is strong enough to solve this problem:

        ln -s /etc/passwd /tmp/need_root_privs_to_read
        exploit_script setuid_root_program /tmp/need_root_privs_to_read
        (exploit_script will fail, because root doesn't own the symlink
        /tmp/need_root_privs_to_read)

The condition in #1 prevents this problem:

        ln /etc/passwd /tmp/need_root_privs_to_read
        (ln will fail, because only the owner of /etc/passwd (root) can
        make the hard link to /tmp)
        exploit_script setuid_root_program /tmp/need_root_privs_to_read
        (fails; there is no link in /tmp to exploit)

One attack left is to try to place a world-writable file in /tmp with
intent to collect the temporary data written by a victim.  To solve this I
would add:

        3. if neither the effective uid nor the owner of the directory
           are the owner of the file (or directory, fifo, socket, etc),
           then effectively AND all permission bits with ~022.  This will
           break IPC that requires two different users to write to the
           same /tmp file, but different users reading the same file
           is fine.

Some things will still break; however, this is hopefully a minimal set.

--
Zygo Blaxell. Unix/soft/hardware guru, was for U of Waterloo CS Club, now for
(name withheld by request). 10th place, ACM Intl Collegiate Programming Contest
Finals, 1994.  Admin Linux/TCP/IP for food, clothing, anime.  Pager: 1 (613)
760 8572.  "I gave up $1000 to avoid working on windoze... *sigh*" - Amy Fong

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic