Subject: Re: How to resolve the filename(s) for a vnode?
To: None <tech-kern@NetBSD.org>
From: Gerhard Sittig <Gerhard.Sittig@gmx.net>
List: tech-kern
Date: 10/19/2005 01:14:56
On Tue, Oct 18, 2005 at 14:02 -0700, Bill Studenmund wrote:
> 
> On Mon, Oct 17, 2005 at 10:32:28PM +0200, Gerhard Sittig wrote:
> > 
> > I'm currently porting Dazuko to NetBSD (this project allows for on
> > access AV scans or rule set based access control or file access
> > monitoring and logging or postprocessing created files or adding a
> > trashcan with unerase capability or whatever one could come up with when
> > given a transparent hook into filesystem activity and the possibility to
> > deny access -- see http://www.dazuko.org for details).  The idea is to
> > intercept file accesses and allowing or denying them after having the
> > access checked by userland daemons.
> 
> Sounds a lot like dmfs, the Data Migration File System, which I worked on 
> when I was at NASA/Ames. Our main thing was to move the file to tertiary 
> storage, and then restrict access until the file was fully restored.

Wow, another interesting environment where such a file access hooking
mechanism is useful or even essential. :)  It's nice to see that there
is real demand for this kind of project (besides AV scanners which are
not that kind of selling point under UNIX as they are on e.g. Windows).

> > [ hooking syscalls vs generic VFS hooks ]
> > 
> > So I thought that a VFS layer would be the way to go -- it's nice and
> 
> It is.

Yes, I would not really like to drop the VFS approach and return to
sycall hooking.  It may work fine (it does for all the other platforms
Dazuko supports) but it's not half as nice as a VFS layer is.

> > But some issues still prevent my implementation from being really useful
> > (or even being used in production). :(
> > 
> > Resolving the filename (at least one of them) for a vnode is not
> > supported by the OS directly.  FreeBSD has vn_fullpath(), MacOS X has
> > vn_getpath(), Linux has __d_path() although it's not public, NetBSD
> > seems to lack such a routine.  From the CVS logs of later versions (3
> > and 4, I currently use 2.0.2) I could not see that such a thing was
> > introduced -- and would be glad to be wrong here.  So I had to roll a
> > resolving routine myself.  That's where even more problems are bubbling
> > up. :)
> 
> The file name will not work right. At all. Don't use it.
> 
> I'm sorry that this will mean a change to the project, but something will 
> have to be done.

Hmmm.  The Dazuko project is not mine, I'm just contributing.  The API
is quite stable and some commercial applications rely on it (and
appreciate the compatibility of Dazuko across all of its versions ever
released).

Expanding the API may be possible, changing it is not. :(  But you
provide an interesting solution(? workaround?) below.

> What you want are inode numbers and generation numbers. That's what dmfs 
> used.
> [ hardware setup snipped ]
> 
> The point is it was a VERY LARGE and very successful system. It ran for 
> almost a decade, and was finally turned off as the Convex systems were not 
> y2k-compliant.
> 
> Inode numbers worked great. File names would NOT have worked at all.
> 
> Unfortunately inode numbers aren't exposed to userland. However, they come
> conveniently bundled (with generation numbers) in file handles. And thanks
> to my dmfs work, file handles ARE readily exposable to userland. :-)
> 
> In your VFS layer, when you have a node you want to ask about, all you 
> have to do is call VFS_VPTOFH() and you'll have the file system-specific 
> part of the file handle. Add the 16-bits of mount-point specific info 
> NetBSD adds, and you have the file handle.

So this kind of handle (internal fh representation derived from the
vnode) is NetBSD specific?

The nice thing about Dazuko is that it has an identical API across all
supported platforms.  It currently runs on UNIX versions only, but in
theory can support completely different platforms like DOS or Windows.
The platform specific parts are well layered and hidden from the API
user.

But again you suggest a possible solution below.

> If userland needs to adjust the file any (needed for tertiary storage, not 
> necessarily for what you're doing), fhopen() can let root open the file 
> w/o knowing the path name (yes, that's why only root can do it).

For filename based rule set checkers the filename would be useful.  For
content filters the filename is not of too much concern, the file's
content is of interest and can be accessed with the fh determined above.

This would mean that loggers are out of luck here, scanners could
continue to work.

> [ filename resolving unreliable, ambigious, subject to races ]
> 
> File handles are MUCH more convenient as you avoide all the the name-space 
> tracking issues.
> 
> What you might do as an intermediate step is turn the file handles (well 
> fsid part of it only; mount point info can change from boot to boot) into 
> hex strings (sprintf(buffer, "%02x%02x%02x%02x%02x%02x%02x%02x", the bytes 
> in the fsid)) and pass those to the userland tools for now.

This may be a way to use file handles internally (and be glad that they
are a much more reliable way to specify "this file the vnode belongs
to") while keeping the Dazuko API and pass up filenames to the userland
daemons.

Filenames passed up from Dazuko to the userland daemons may be processed
in any way an application may want to handle the filename.  It can be
logged, ignored or used for open(2)/fopen(3) calls.

When a userland daemon accesses files with open(2)/fopen(3), this can be
any regular file or the pseudo filename previously gotten from the VFS
layer as the handle for the vnode the access is to be checked for.  This
means that the open(2) syscall (or the appropriate lookup and open vops)
need to be hooked.  To remap pseudo filenames to internal file handles.

I have to think about this for some time and see how to best solve this
problem.  It looks like the VFS layer has to
- intercept the create, open, close, unlink, rmdir, rename vops to catch
  these file accesses, get the fh for the vnode and pass the event up
  with the fh encoded in a pseudo filename
- hook the lookup vop to catch accesses to the pseudo filenames, remap
  those pseudo filenames to their internal fh or use the original lookup
  method for regular path names

This sounds like I could implement it in the next weeks and see how well
this works (and how bad it is that loggers won't be too useful, only
scanners work without noticing too much of this internal change).  Then
I need to get the code reviewed to get vnode locking right.


Thank you very much for your telling me what's wrong with my initial
vn_fullpath() request and offering a reliable way to address a vnode
from the "filenames namespace". :)


virtually yours
Gerhard Sittig
-- 
     If you don't understand or are scared by any of the above
             ask your parents or an adult to help you.