> In the CAOS model I
> presumed a starting process is put into a 'black box', a can-do-nothing
> position. Since this means that process can't do anything at all, I
> introduced this initial 'request', where the process can state the
> resources that it will need in order to become usefull. It is asumed
> that since the process has been considered by the system as valid to
> start, the process is allowed to state its needs.
There are several problems with this model.
authority to some CPU schedule
authority to an address space, and any necessary mappings
therein
authority to the requestee
Pragmatically, it also will in common cases require:
authority to take page faults, and therefore authority to acquire rights to storage
This is quite a lot of authority. Actually, it's most of the authority that most programs will *ever* need.
> I thought of this 'request' when I was thinking about non-cpu-specific
> process startup methods and non-platform-specific system calls and it
> came as an obvious solution which obeys the
> can-do-nothing-without-authorization rule...
As you can see from above, it hardly obeys the "nothing without authorization rule"
> > The best way to keep hold of the capabilities that a process needs is
> > to grant them from the beginning and ensure that they are never lost.
>
> This was the original idea. The 'request' above is the means a process
> can obtain the needed capabilities. But since in the low level we always
> come to the terms of functions, I translated 'capabilities' to
> 'functions that perform specific actions on objects'.
>
> Do you think that this translation is a good thing? I see difficulties
> in managing unnamed objects but at the time I felt that it's worth a
> thought.
I disagree that in the low level we always come to the terms of functions. I think that at the low level, we always come to a function performed on an object. A read call is performed on a file descriptor. An open call is performed on a directory passing a string. etc. etc.
In fact, I cannot think of even one example function that is
unconditionally safe on all objects, unless it is one that returns
immutable state. The result of such a function never changes, and the
function is therefore not useful.
Even being able to ask an arbitrary object something very simple like
it's size provides a communication channel between parties.
Indeed, the fundamental security issue is not what functions can be
performed, but what objects can be reached. Functions are very
broadly classifiable into activities that provide read, write, or
read-write access to an object. That plus the identity of the initial
objects is sufficient to make arguments about information flow in the
system, and therefore about the security of the system overall.
Conceptually, then, it isn't the functions that make or break the
security of the system; it's the object identities. From experience
in the theoretical security work that Sam Weber and I did, I can
> > In a capability system it cannot. The child either holds a capability
> > or it doesn't. There is nothing in the capability that records where
> > the capability came from. Once transferred, the sender has no control
> > over how the receiver uses the capability.
>
> Mhm. So every capability can in every point in time have only one
> holder?
I'm not sure where you got that idea. Perhaps I should have said 'transferred or copied.'
Think of pointers. If you and I each hold pointers to the same object, the pointers live at different locations but contain the same bits. The question is whether you wish to think of these as one pointer or two. Depending on the purposes of our discussion, either answer could be correct. To a garbage collector these are different pointers. For programmer purposes it's often sound to think of them as the same pointer.
In the same way, if you and I hold separate copies of a capability to the same object conveying the same authority, we can speak in either sense correctly. Each capability has a unique holder, but pragmatically it is useful to think of two parties as holding the same capability.
What I was really trying to say is that a capability does not record information about how it has been copied. The holder knows what capabilities they hold, in the sense that they can learn by experiment what those capabilities seem to do. The capability does not know its holder, and in most capability systems a capability invocation does not convey to the recipient any information about the calling process (such a design would be a hybrid protection model).
This is part of what it means to say that holding a capability is a necessary *and sufficient* condition for performing the capability-authorized actions on the object designated by that capability.
> > Observation: while you could build a modified capability system that
> > used hierarchically constrained access rights, you would create to
> > problems in doing so:
> >
> > 1. Undesired communication channels inherent in the access control
> > hierarchy itself.
> > 2. Variable-length capabilities.
> >
> > >From an implementation perspective, capabilities *really* want to be
> > fixed size. Imagine programming a system with variable length
> > pointers...
>
> Hm. Can you give an example of the two mentioned problems?
Sure. Suppose you record hierarchy. You either must bound the depth of the process hierarchy so that you can bound the space required to record that hierarchy of transfers, or you must dynamically resize the capability. If you dynamically resize the capability then preallocating storage for it becomes a mess -- thus the analogy to variable size pointers.
Worse, the space for the dynamically sized capability must come from somewhere, and the amount of available storage in the storage agent is a source of information transfer. By combining downward transfer (allocate storage) with deleting capabilities (free storage) and some error correction coding, a fairly high bandwidth channel can be constructed by querying the amount of space available from the storage manager (several hundred kilobits/second). The guy on the inside transmits data by moving the available storage up and down. The guy on the outside watches the changes in the water level.
Actually, there's a worse problem. In general, hierarchical transfer isn't real desirable. You want any two communicating processes to be able to transfer capabilities, which violates the hierarchy model.
> > The graph shows lines for several choices of X, several crossing
> > speeds, and several numbers of crossings.
>
> Do you have an URL on this?
Sorry, I'm afraid I don't. I believe it appears in one of the L3/L4 papers, which you can find off the L4 web site. I'ld send a URL for that, but Penn's web server isn't cooperating at the moment.
> I picked the term 'capability' because I felt it described quite
> well the basic idea of the model that I'm trying to develope. I was
> not aware of existance of any such systems at the time...
No problem. New ideas deserve new, catchy names.
> The idea that I was (probably in a very clumsy way) proposing is
> quite similar to a hyerarchycal capability model that you were talking
> about.
Hmm. If you will not take it amiss, let's talk about whether the hierarchical restriction buys you. I'ld propose two questions to start with:
In fairness, I should say that I think the answers are (1) it isn't, (2) none, (3) none, actually more complex. I think I can support those answers.
shap