[LWN Logo]
[Timeline]
Date:         Fri, 15 Dec 2000 21:12:58 -0800
From: Kris Kennaway <kris@FREEBSD.ORG>
Subject:      Re: /tmp topic
To: BUGTRAQ@SECURITYFOCUS.COM

--SUOF0GtieIMvvwua
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Thu, Dec 14, 2000 at 10:10:07PM -0800, Octavio / Super wrote:

> Is there a standard or a guide or a "HOWTO" <g> on using tmp
> directories safely? About using mkstemp(), assigning correct
> permissions, erasing the file at program termination, etc.

Use mkstemp() for making temporary files. If you can't use mkstemp()
then make yourself a directory using mkdtemp(), which is protected
from the outside world and you can be as insecure as you like within
it. If you really have to use the insecure mktemp() then use lots of
X's - I suggest 10 (if your libc allows it) so that the filename can't
easily be guessed (using only 6 X's means that 5 are taken up by the
PID, leaving only one random character and allowing an attacker to
mount an easy race condition) [1]

Never "roll your own" temporary file creation routine. Chances are you
don't know what you're doing and will get it wrong. Use the interfaces
helpfully provided to you by your libc vendor (described above). If
they don't provide these interfaces then yell at your vendor until
they do, or port the functions from a freely available libc such as
the FreeBSD/NetBSD/OpenBSD libc. Beware of deprecated, insecure
interfaces like mktemp() or tmpnam() which should be documented as
being insecure by your vendor.

Don't ever reuse a temporary filename (i.e. remove and recreate it) -
no matter how you obtained that "secure" temporary filename in the
first place (e.g. mkstemp()). An attacker can observe the original
filename and hijack it before you recreate it the second time.

If you ever want to make a file in /tmp or a world-writable directory
(or group-writable, if you don't trust the group) and don't want to
use mk*temp() (e.g. you intend for the file to be predictably named),
then ALWAYS use the O_EXCL flag to open() and CHECK THE RETURN
VALUE. If you fail the open() call, then recover gracefully
(e.g. exit).

Always use appropriate permissions - e.g. only allow world/group
access if you need the world or a group to access the file, otherwise
keep it mode 600.

Clean up after yourself, either by using an exit handler, or making
use of UNIX filesystem semantics and unlink()ing the file immediately
after creation so the directory entry goes away but the file itself
remains accessible until the last file descriptor pointing to it is
closed. You can then continue to access it within your program by
passing around the file descriptor.

Kris

[1] FreeBSD has recently changed the mk*temp() family to get rid of
the PID component of the filename and replace the entire thing with
base-62 encoded randomness. This drastically raises the number of
possible temporary files for the "default" usage of 6 X's, meaning
that even mktemp() with 6 X's is reasonably (probabilistically) secure
against guessing, except under very frequent usage.

http://www.FreeBSD.org/cgi/cvsweb.cgi/src/lib/libc/stdio/mktemp.c.diff?r1=1.19&r2=1.20

--SUOF0GtieIMvvwua
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE6OvnUWry0BWjoQKURAt2wAKC+SY7UIwt8uR3HPuhM6lIYvlR0ZQCgjr+g
a1yH9FXtYDtjGWHjoR1U+Dc=
=Ucxe
-----END PGP SIGNATURE-----

--SUOF0GtieIMvvwua--