Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 06 Jan 2003 19:32:23 -0800
From:      Terry Lambert <tlambert2@mindspring.com>
To:        Pawel Jakub Dawidek <P.Dawidek@prioris.mini.pw.edu.pl>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: Caching [sugestion].
Message-ID:  <3E1A4A47.90B2ABDD@mindspring.com>
References:  <20030105215024.GB99855@prioris.mini.pw.edu.pl> <3E18B97A.32ABAE7@mindspring.com> <20030106074005.GB6825@prioris.mini.pw.edu.pl> <3E1A1702.2E592C16@mindspring.com> <20030107003613.GG6825@prioris.mini.pw.edu.pl>

next in thread | previous in thread | raw e-mail | index | archive | help
Pawel Jakub Dawidek wrote:
> Yes, I know that (sugestion of getting file names (not directory names only)
> from vnode was mistake). That's why I think that there should be some
> caching mechanism that should remember file name of every opened file,
> name of executable and working directory.

You are missing the point.

> Example rules:
> 
>         We want to permit those operations:
>         - opening file /etc/master.passwd for read only,
>         - opening files that match to /tmp/temp.*  for write,
>         - changing mode of files /tmp/temp.* to '0666', BUT via fchmod(2).

Here is an example:

    ln /etc/passwd /tmp/temp.hack_Pawels_passwd_file_by_abusing_a_bad_rule

    fd = open( "/tmp/...", O_RDWR, 0);

...Oh look, I've just abused permissions that come from MAC based
on inheritance, with a hard link, in order to hack the password file...


>         How to do that correct?
>         There is no chance to do this in simple, clean way.

Which is why most people never try to do it.

The "simple, clean way" is to disallow hard links, and cache the
parent directory inode on every VOP_CREATE and VOP_MKDIR operation.

The "less simple, but clean way" to do it is to create a file system
object called a "link node", for use by hard links, and to seperate
the vmobject_t reference out of the vnode, so that each path gets a
seperate vnode, and each vnode that's actually an object alias gets
the same vmobject_t reference, instead of having its own.

Other than that, you really can't do what you want, because your
cached information is going to be incorrect, if you access the same
file via two hard links.  When you go to apply MAC's based on the
two different paths, only one of the paths is going to have it's MACs
enforced correctly, and the other one won't, because of the order of
the objects in the cache (assuming your code is even smart enough to
make two cache entries at all).


> I've returned to my old, ugly way - caching filenames on open(2) -
> it's working fine, but is complicated, because I need to catch calls
> of p->p_fd->fd_ofiles[X]->f_ops->fo_close() functions.

It's worse than that: you are screwed if you use a POSIX domain socket
to pass an open descriptor to another program, and in about 5 other
cases where all a nwew program receives following an execve(2) is a
reference: the receiving program is not going to have the cache reference,
because all it's getting is an open descriptor, not a file reference.

This is going to be *particularly* bad for programs that open up a
file, which they are permitted to open because of their inherent
priviledges, and then they relinquish those priviledges, while
keeping the file open.  As I said before: caching is bad, and the
open is a result of a cached priviledge reference.  Unless you force
the file closed at that point (breaksing some of these programs), you
break your MAC-based security model.

The only reasonable approaches are to not try to do this thing, or to
ensure that there is a 1:1 mapping between vnodes and open file
instances, vnodes and file system objects, and that hard links become
discrete file system objects.

-- Terry

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3E1A4A47.90B2ABDD>