On Sat, Dec 8, 2012 at 2:33 PM, Andrew G. Morgan <mor...@kernel.org> wrote: > On Fri, Dec 7, 2012 at 10:39 AM, Andy Lutomirski <l...@amacapital.net> wrote: >> It breaks down because, currently, users with nonzero pI have no >> direct ability to wield the capabilities. That means that every >> single binary with fI bits set needs to be as careful as a setuid-root >> binary to avoid leaking privilege to the caller. (Obviously, binaries >> with fP set need to be careful. IMO binaries with only fI set should >> not need to exercise any particular care to defend themselves from >> their callers.) > > True. But what about protecting the system from privileges they didn't > expect to have?
I don't really understand. If I call rm -rf /, expect it to do nothing, but I inadvertently had CAP_DAC_OVERRIDE and passed it on, then I just shot myself in the foot. I don't see what this has to do with access control. > >> I'm obviously missing some fundamental (and probably historical) issue >> here, so let me ask the following straw-man question. Suppose >> capabilities worked like this on exec: >> >> pP' = pI | (fP & pB) (i.e. the current way, except that fI always has >> all bits set for every binary on the system) >> pI' = pI (unless !SECURE_NOROOT and uid == 0 or euid == 0, in which >> case pI' = pP') >> >> with the added restriction that pI is always a subset of pP (i.e. >> dropping a bit from pP (on exec or otherwise) drops that bit from pI). >> >> What would be wrong with this model? (Let's pretend for now that >> capabilities had always worked this way, so there's no change of >> behavior to worry about.) >> >> - The sendmail capability bug wouldn't happen: pI has no effect on >> setuid-root binaries. > > Are you saying that setuid-root is required for a program like > sendmail to work? Forever? No. If anyone writes a modern program like sendmail, it would be capability-aware and it wouldn't have the same problem. (And presumably it wouldn't use setuid(2), which is terminally broken.) > >> - There would be no difference between a user being trusted with a >> capability and being inh-trusted with that capability, since the >> latter concept wouldn't really exist. > > See below. It's key to see that it is not people, but programs that > require privilege. It may be key, but I am completely unconvinced that this is the right model. Windows has a capability system (called privileges, not capabilities) with full inheritance and no per-binary anything. It's worked just fine for decades, and it is completely immune to sendmail-like bugs because it *does not have* any concept of privileged binaries. It may have a classic MS-style overcomplicated APIs, but the model is quite simple and easy to understand. > I think you have correctly determined a key difference (a fundamental > feature!) of the model. > > For an explanation, please search for "key insight" in the OLS paper: > > http://ols.fedoraproject.org/OLS/Reprints-2008/hallyn-reprint.pdf > > Also, see p310+ of the first document linked to on the page Casey pointed to: > > http://wt.tuxomania.net/publications/posix.1e/download.html > > which has quite an elaborate explanation of how this model was > designed, and what the authors were trying to achieve. I read the "key insight", although I admit that I gave up before I found page 310 of the old POSIX draft. (Why is the rationale nowhere near the beginning? I still can't figure out what the default value of fI is.*) I see no justification for *why* the authors were trying to achieve that. Again (any mainly because I feel like there's a giant mental disconnect here in that I really don't understand wtf the current / POSIX system is trying to accomplish): what would be wrong with a model in which capabilities could be freely passed from parent to child? Why would it be insecure? Why would it be error-prone? There's got to be *some* reason why it's not in use right now. I can speculate as to the reason the current scheme is barely used except internally to a few daemons (and why AFAIK there is no one making serious use of fI): it's basically incomprehensible. Security systems should be simple enough to understand and analyze. "Here is the set of things that I and my descendants can do" (the Windows model) is simple. "Here is the set of things I can do (pP). Here is a different set of things that a certain class of my descendants can do (pI). Here is the class of descendants that can do those things (fI). And here's a different class of descendants that can do things no matter who invokes them (fP)." is really hard to understand. It's especially bad because granting CAP_DAC_READ_SEARCH to user "foo" doesn't mean anything. Is he authorized to back things up to encrypted storage? Is he authorized to read any file for any purpose? Is he authorized to read things on behalf of properly authenticated remote users? No one knows because it depends entirely on what set of binaries with CAP_DAC_READ_SEARCH=i he can find. * I see "If pathconf() indicates that {_POSIX_CAP_PRESENT} is not in effect for a file, then the capability state of that file shall be implementation defined." I think this means that the designers didn't actually decide whether fI should default to all zeros or all ones. --Andy -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/