Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Feb 1999 19:11:18 +0000 (GMT)
From:      Terry Lambert <tlambert@primenet.com>
To:        julian@whistle.com (Julian Elischer)
Cc:        dillon@apollo.backplane.com, mark.hannon@stockholm.mail.telia.com, freebsd-hackers@FreeBSD.ORG
Subject:   Re: Change to inherit nodump flag?
Message-ID:  <199902101911.MAA21201@usr07.primenet.com>
In-Reply-To: <Pine.BSF.3.95.990209151210.5802O-100000@current1.whistle.com> from "Julian Elischer" at Feb 9, 99 03:15:50 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> I don't think this is a good idea
> 
> a better idea is to make th eapplication not descend into trees that have
> the nodump bit set on the directory.
> 
> you can't "inherrit" all the way up a directory tree when it's moved 
> into a directory with the nodump flag set.
> 
> (I have the same problem with the SUIDDIR option in around  the same
> piece of code..)

The soloution to this is to grab the inheritance from the upper
level directory after traversing up, and to make a distinction
between "implied" and "explicit".

The problem you have with the SUIDDIR code is no different, if the
credentials are obtained by inheritance to root.  When you traverse
to root, if you hit an entry that has an "inherit me" semantic, then
you impose the inheritance, and cease traversing.

The failure case for this is hard links, where the parent is
ambiguos.  This is a solvable problem.


To resolve this, you need to have the concept of referring inodes,
where a hard link takes an inode of type "hard link".  The intent
of making this a unique inode number is to differentiate one link
directory entry from another.

You make a chain of these, so that you can change which one is "real"
in the case that the "real" one is unlinked, and the reference count
is still non-zero.

Then you store the parent pointer in both the "real" and the "virtual"
hard links.

[ Obviously, links in the same directory would not require a seperate
  inode, since the parent is shared; but you must deal with moves in
  and out of directories, which can be tricky and expensive enough
  that it's probably worth the inode to avoid the problem. ]

To fully realize this, you need the concept of alias vnodes.  This
buys you the ability to ask "what path was used to open this file
that is currently open?".  In order to answer this question, the
file opened via one hard link path must have a different vnode to
refer to the different inode, but must be backed by the same backing
object (inode).

Thus, any inherited attributes will vary by path used to access the
object, which is as it should be for inherited attributes.


You can achieve the same effect, presuming directory hard links are
disallowed (which they should be, since they make x/../x nontransitive)
by caching a reference to the directory vnode that got you any given
vnode in the vnode structure itself.

This still requires aliases for vnodes be generates, and that sibling
aliases be referenced, so as to keep a single vm_object_t in common
between all referencing vnodes.  Siblings in the same directory, unlike
the inode approach, can use multiple references to the same vnode
without incurring the overhead of having to search the inodes in a
directory for siblings (in the inode case, they are hidden, since
the inode numbers don't match; you have to reference the inode
contents; though there is something to be said for faulting inodes
into core as a result of a directory traversal, since a subsequent
stat or open is likely).  The lossage on this, though is that you
won't be able to distinguish sibling names for hard links in the
same directory.  This is no real loss for almost all conceivable
applications.


This has the advantage of working on all FS types, but the disadvantage
(which may be considered an advantage) of not immediately reflecting
change in inherited attributes that result from a hard link being
moved.  This, since all file instances are, in the limit hard links.

This is a disadvantage if the intent is to allow revocation, and an
advantage if the intent is to "give away" access irrevocably.  This
particular "advantage" fits with the idea that you can open a file
for read/write, and subsequent revocation of write access is not lost
(e.g., SUID/SGID programs take advantage of this type of "give away").
This quickly becomes a "disadvantage" if you try and fit it into the
model where even a file opened read/write is unwriteable in the case
of a mount update of an FS from read/write to read-only.

Nice thing that UNIX has a uniform security policy.  ;-).  My
recommendation would be to employ the "give away" model by default,
and allow a brute force revocation, to be paid for by only those
applications/installations that require revocation.


In any case, the other "disadantage" (which I see as "no big deal")
is that references to the parent vnodes must remain in core so
long as the children are referenced.

This is generally "no big deal" because the refrence is most likely
to be a reference to a vnode that is held open anyway as the processes
current working directory, and because of N:M locality (for N open
files, there will be M "open" parent directories, where it is generally
true that N >> M).

Thinking about this makes you want to rationalize all vnode references
as if they were open instances -- e.g., vnode references by the directory
name lookup cache -- doesn't it?  Add a reference for an entry into the
cache, add a reference for an open, add a reference for a parent pointer,
etc. -- they all become the same macro in sys/vnode.h.


					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.

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?199902101911.MAA21201>