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>