Bugtraq mailing list archives

Re: another /tmp race: `perl -e' opens temp file not safely


From: shalunov () MCCME RU (stanislav shalunov)
Date: Sun, 8 Mar 1998 08:38:20 GMT


This is starting to get off topic, I am afraid, but still...

"deraadt" == Theo de Raadt <deraadt () cvs openbsd org> writes:

All this complexity of trivial things (just open a temp file) is
one of the reasons I think the whole idea of /tmp is a fundamental
misdesign and eventually one should be able to chmod it to 755
(while programs should use per-user TMPDIRs).

 deraadt> Which, as I've said before, works REALLY well for setuid
 deraadt> programs.
 deraadt> Imagine:
 deraadt> TMPDIR=/
 deraadt> Or how would you solve that problem?

You probably mean rather something like
        TMPDIR=$HOME/tmp privileged & symlink_exploit
or I did not understand your argument.

In fact what I had in mind was _not_ honoring TMPDIR environment
variable but rather some fixed-dir mechanism (or at least TMPDIR does
not to be set by default but supported for flexibility--/home almost
full or want to use a local drive rather than something NFS mounted).
The good old 1777 /tmp is still necessary in Unix environments (to get
rid of the beast completely one will have to change a lot of stuff).
The pseudocode to decide where to store temp files might look like
(its place is in the function that all mktemp style functions call):

        home = euid's home dir from /etc/passwd
        homeok = ((home is writable for euid) and
                  (home/tmp doesn't exist or is a dir writable for euid))
        groupok = (egid == gid) or (euid != uid)
        noprivs = (egid == gid) and (euid == uid)
        if noprivs and environment TMPDIR is set then
          tmpdir = $TMPDIR
          if tmpdir and everything above is writable only by their owners then
            safe = true
          else
            safe = false
          fi
        else if homeok and groupok then
          tmpdir = home/.tmp
          safe = true
        else
          tmpdir = /tmp
          safe = false
        fi
        if tmpdir doesn't exist then
          /* They could spot a race here, but what for?  Or are there
             any OSes that will follow symlinks creating dirs? */
          success = mkdir tmpdir with perms 0700
          assert success
        fi
        if not safe then
          make all calls not considered secure log something
          /* logging without openlog() first */
        fi
        generate unique filename in tmpdir
        ...

Well, something like this.  It should make most /tmp problems go away.
The only programs that will still be vulnerable with this approach--if
they do not use (a call using) O_EXCL--will be those that are setgid
or those that are setuid to a user with a wierd home (like bin or
httpd or ftp).  So, in practice, only setgid programs (because of the
fact groups do not have homes) and third party stuff with hardcoded
/tmp will be suspect.  There is only a very limited number of setgid
programs.  And they all are in the OS so they can be audited.  Many
problems with third-party software are solved (if some third party
program has /tmp hardcoded and insists on insecure running you'll at
least get log notices).

With this approach you win some robustness and lose nothing (except
inodes for ~/.tmp--like 500K of disk space on a machine with 1000
users and a reasonable filesystem as ~/.tmp will normally be empty
[clean them on boot and delete files with [ca]time a few days old via
a cron job]).



Current thread: