Subject: Re: funlink() for fun!
To: Matthias Buelow <mkb@mukappabeta.de>
From: Greg A. Woods <woods@weird.com>
List: tech-kern
Date: 07/13/2003 18:58:11
[ On Sunday, July 13, 2003 at 22:25:02 (+0200), Matthias Buelow wrote: ]
> Subject: Re: funlink() for fun!
>
> Of course it is and I only gave this example to show how nonsense
> an "funlink()" call would be -- because the only valid behaviour
> in the current framework (clearing of inode / invalidating all fds)
> would be totally impractical.

Your example was flawed though, even for its intent, since it did not
describe "the only valid behaviour in the current framework".  In fact
it described a completely different bahaviour un-related to the
funlink() call I initially proposed.  I described, informally, the valid
behviour for funlink() as I saw it, along with its API and its
limitations.  I did so in order to make a point and to hopefully help
give some rationale for some other related proposals.

funlink() is the most natural way one naive of the internals of Unix
filesystems might think to use to make it possible to allow one to
safely get away without using temporary directories for temporary files.
Indeed the lack of a funlink() call has been mentioned, and the
consequences of this lack discussed, by several experts in secure
programming practices.

However as I've already said I do agree it is less practical to actually
implement funlink() than it is to simply use the existing mechanisms
which do allow safe use of temporary files in temporary directories.

Unfortunately I still see too many NetBSD programs creating and removing
temporary files directly in /tmp and /var/tmp, and of course the default
sysinst still creates those directories on filesystems which also
contain other sensitive informatoin.  While setting the sticky bit on
those directories can protect most such programs from the most obvious
attacks, I don't believe the most important of these programs
(i.e. those most often run as root) will actively check to make sure
that either the sticky bit is set or at least that the directory is a
mount point.

> Now can we stop this thing?  Or should I also propose some b*llsh!t
> system call and have a hundred-mails long thread debate its uselessness?

I guess you're not someone who enjoys a good academic discussion even if
its merit is only academic, and/or you don't care that people can learn
from it and that it can lead to true innovation of related things,
e.g. O_MKDIR.  I hadn't really considered O_MKDIR before, but having the
occasion to re-read in the right context code designed to facilitate the
safe creation and disposal of temporary files where either a pair of
fchdir() and unlink() calls are needed to be able to do without the
funlink() API that would most naturally come to mind I realized that
this same non-trivial code which allows a process to safely create and
use a temporary directory inside a world-writable directory is complex
enough that re-implementing it even in a library could leave latent
problems that are trivially avoided once and for all by allowing open()
to safely and securely create the new directory for fchdir() to use in
just the same way it can be used to safely create new temporary files.
This same discussion also helped re-enforce the need for the O_NOACCESS
flag suggested by der Mouse so that a file descriptor suitable for
fchdir() could be obtained from a read-only current working directory.

What's most important here is to understand _why_ any of this is
necessary (and indeed why it is necessary to make world-writable
directories their own filesystems too).  People, even relatively well
experience systems programmser, don't always do the right things without
understanding the rationale for doing certain things in certain ways and
without knowing all the alternatives from which one can choose from and
the various pros and cons to those alternatives.

If you or anyone else reading this thread has not already read "Building
Secure Software" by John Viega and Gary McGraw, I strongly suggest you
do so at your earliest convenience.  It's not the first text to discuss
the issues implied by our discussion of funlink() et al, but it is one
of the more complete compendiums of good advice in this field.  Although
I have no idea whether you yourself have read this book or not, I will
say that in general I doubt somoe of the dismissive side-swipes at
thread, such as your own reply to which I'm responding, would have been
made if more people had read and understood as least some of the advice
in that book.

-- 
								Greg A. Woods

+1 416 218-0098;            <g.a.woods@ieee.org>;           <woods@robohack.ca>
Planix, Inc. <woods@planix.com>; VE3TCP; Secrets of the Weird <woods@weird.com>