vn_fullpath() again

Robert Watson rwatson at FreeBSD.org
Wed Sep 7 08:46:35 PDT 2005


On Tue, 6 Sep 2005, Sergey Babkin wrote:

>> Corner cases and their handling *is* important.  Find another way to do 
>> whatever it is you're thinking you can do with "the real name of a 
>> vnode".
>
> This particular case is easy to handle: all that user 1 needs to do is 
> to do fstat() after opening the file and check that the returned inode 
> field is still the same.
>
> On the otehr hand, if there is this new interface to access files 
> directly by inode numbers, why bother with any names at all? If a name 
> is so desirable, then just create a pseudo-fs translation that would 
> convert the text-formatted device and inode number given to it as a file 
> name to an access to the identified file.
>
> Though both this and access directly by vnode number open a security 
> hole: in many cases the access to files mught be actually limited by 
> making the directories unreadable to the unwanted users. Bypassing the 
> directories bypasses this "security by obscurity".

FYI, Mac OS X has a service called volfs, mounted as /.vol, which does 
exactly this.  It was required because Mac OS 9 allowed applications to 
open a file by path, and then get back a persistent reference ID that 
would work across reboots.  This is how applications like Microsoft Word 
can open a file that appears in the "recently opened file list" even after 
it has been renamed or moved from one directory to another, and how Mac OS 
9 shortcuts could span file systems even after renames and moves.

In Mac OS X, these file handles are converted into requests against volfs, 
and nominally bypass the directory structure.  In earlier Mac OS X 
versions, this resulted in possible security problems, if folder 
permissions were assumed to protect their contents.  As I understand it, 
in newer versions, they attempt to construct a path which will then be 
followed to open the file, in order to cause appropriate permission checks 
to occur.  This process works OK on HFS+, but very poorly on other file 
systems.  You'll notice, though, that if you look at the audit event 
stream, during first use you'll often see normal path names, but that as 
the system peters along, the vn_getpath() call in XNU will start to return 
volfs names -- typically when that is the most recent or only path that 
has been used to reach a file, since the name mechanism is based on the 
assumption that the name cache holds the name you want.

In practice, systems like Solaris and Irix assume that names are a path 
that is important at the time of lookup for audit purposes, since the path 
you follow affects the permission checks that take place, but that once 
you get to the file what you really want is the device and inode number, 
since only that combination usefully persistently identifies the file. 
Ideally you have the generation number in there also, as well as mount 
events, etc.  This is why, if you look at Solaris BSM streams, you get the 
lookup path only at time of open (or stat or whatever), and after that, 
just a description of the vnode/inode properties, not a path.  In our 
implementation of audit for Mac OS X, we try a bit harder to generate 
paths, since HFS+ is fairly good at it, but you will likely get no path, 
or a volfs path, for files that reside in a non-HFS+ file system, have 
only been accessed using Carbon APIs, and so on.

Robert N M Watson


More information about the freebsd-hackers mailing list