Subject: Re: funlink() for fun!
To: Matthias Buelow <mkb@mukappabeta.de>
From: Greg A. Woods <woods@weird.com>
List: tech-kern
Date: 07/14/2003 16:58:39
[ On Monday, July 14, 2003 at 21:46:15 (+0200), Matthias Buelow wrote: ]
> Subject: Re: funlink() for fun!
>
> Ok, I didn't know about file handles.  They're also not want I meant.

Oh, I know they're not exactly what you meant, but you can't (easily)
have what you meant -- it's next to impossible (and certainly not ever
practical) to implement what you wanted with any unix-like hierarchical
filesystem that allows multiple hard links and rename operations on
directories.

What you're suggesting is massively more complex and obviously much more
invasive than my simple little funlink(2) idea!  ;-)

(and it doesn't seem to offer much beyond what funlink() and/or
O_NOACESS (and maybe O_MKDIR) can offer)

> I wanted a handle on the directory entry (essentially the pathname) as
> some kind of invariant representation of a particular directory entry
> at a discrete point (originally specified by pathname).

But a directory handle isn't a representation of a pathname (though one
can intuit the name of the directory by walking back down to the root
directory and ascertaining the pathnames of each previous directory
along the way).

You'd have to do this for all the directories in the path, and you'd
have to somehow lock all the directories in the path in order to make
sure that every rename() involving any such directory could
co-operatively update those handles.

I.e. you're just beginning to enter the twisty little maze of passages
all alike.

> A second idea is that open(2) returns not only a file descriptor but
> also such a handle.

If you want to keep the open(2) API intact then you could try to
implement it as a function call that's the moral equivalent of
fhopen(getfh(path)).  Either way the only logical thing to do (without
affecting the open() API) is to make it easy to translate a file
descriptor back into the file handle it came from.

I haven't thought of the implications of having file descriptors in
user-land, though presumably everything could be transmuted to use file
handles, including even descriptor passing through AF_LOCAL sockets.
The tricky parts involve seek pointers and such -- and that's something
I always get very confused about unless I diagram it all out on a big
sheet of paper.

>  Open() already compromises in dealing with
> pathnames anyways, so we could be a bit relaxed about the strict
> division between file (inode/devno) and a particularly directory entry
> in the context of open().

That's part of the problem, not the solution.  Please study the example
safe_dir() implementation in the book I referenced.  You can find it in
here:

	http://www.buildingsecuresoftware.com/bss_examples-1.0.tar.gz

(in the file "EX9-5")

> > Of course these calls (including getfh()) are currently restricted to
> > the superuser because they have not had the necessary ACL semantics
> > defined for them.
> 
> I don't understand why they're restricted to the superuser -- getfh()
> does return EACCES when it can't access the directory of the specified
> pathname and fhopen() surely checks for permissions on the file
> itself.

Unfortunately that's not (yet) true.  To quote from the fhopen(2) manual
page on NetBSD:

     These functions provide a means to access a file given the file handle
     fhp.  As this method bypasses directory access restrictions, these calls
     are restricted to the superuser.

fhopen() and fhchdir() would have to have full permissions checks added
to them.  In the fhchdir() case, for example, the operation would have
to be failed with EACCESS if the directory was not searchable by the
effective user or group of the caller.  Such an implementation of
fhchdir() would truly eliminate the need for der Mouse's O_NOACCESS.

As always though, the problem with new system calls that "violate"
various assumptions about levels of protection in an OS there are risks
that cannot easily be predicted.  getfh() suffers many the same kinds of
problems that procfs did, and that some ptrace() features still do.  One
would have to do some extrememly careful and detailed goal-oriented
analysis of the potential vulnerabilities before one took on the task of
making getfh() et al available to unprivileged users.

I seem to recall some more specific discussion on the issues with
providing secure unprivileged use of getfh() and fhopen() and so on, but
I forget where and what the details were.

-- 
						Greg A. Woods

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