[E-Lang] Re: Java 2 "Security"

Scott Smith scott@cs.jhu.edu
Tue, 02 Jan 2001 12:45:00 -0500


"Mark S. Miller" wrote:

> Arthur van Hoff and Schmidt eventually resigned, but by then Java was
> already committed to the Security Manager + Stack Introspection
> architecture.  This architecture is fundamentally "Principal" oriented, with
> ClassLoader identity serving to identify the Principal.  Principal-oriented
> architectures generally assume that when A invokes B, that B's actions
> honestly represent A's intentions.
 
...
>  Despite the history, the resulting system may or may not
> actually be good.  We still need to argue any case on its merits.  But an
> historical perspective can provide some orientation.
> 
History is hard to read.  Word War II is a good example of how sheer
pressure can lead to amazing scientific advances.  It does provide a
good excuse for the Java folks.  By the way I should say I also think
the Java security architecture is not the long-term solution (and, I
think the same for the capability model as used in e.g. E).

> >To me it
> >certainly provides something, and what it provides is not subsumed by
> >capabilities, and so it seems interesting. In terms of the low-level
> >information flow, capability flow is a flow of access rights through the
> >store, and stack inspection can be represented as a flow of access
> >rights down the call stack.  These are very different dimensions.  But,
> >I don't claim much of an understanding beyond that.
> 
> I would be fascinated to see what it provides that is not subsumed by
> capabilities.  I think we all would.
> 
> Regarding "stack" vs "store", as Hewitt teaches (something like "Control
> Flow Seen as Patterns of Passing Messages" in the early 70s.), call, return,
> and all other control transfers can all just be seen as message passing
> operations.  There's nothing magic about the stack.  Most others have
> learned this in turn from the Continuation Passing Style transformation that
> Scheme got from Actors.  As Hewitt explains, a message pass is just a "goto
> with parameters".  Actors deal with the flow of authority through all
> in-model causal pathways, ie, all message passes, whereas Java 2 treats the
> stack as a special category.  So who subsumes whom?

You can take "stack" to be equivalent with "patterns of message passing"
for the purposes of this comparison.  The important stack-pattern in a
pattern of messages is X waiting-for Y waiting-for Z etc, a trail of who
is waiting for results from whom which de facto constitutes a stack
whether it is explicitly represented or not.

So, This particular pattern of waiting-for is quite distant from the
store structure of a run-time.  They both can be embedded in each other
(store-in-stack via the state-passing transformation of Strachey, the
stack-in-store by CPS or the RISC architecture method of explicitly
saving return address), but embeddings in each direction are complex. 
(Also the store-in-stack embedding doesn't preserve the security
properties of capabilities so for our purposes here its not so good)

Getting back to your question above of what is not subsumed by
capabilities: one of the properties of the Java security model is the
ability to temporarily raise a privilege so a more sensitive operation
can be performed.  A flag is put on the stack (i.e. in the messaging
wait-for chain) which signifies the point at which a privilege is
raised, and the privilege is raised until that frame is popped (there
are various other aspects of the model I am skipping).  To get this
effect in a capability system you need to explicitly pass to each method
call below the point where the privilege was temporarily raised the fact
that this privelege was raised.  Otherwise the information that a
privilege is temporarily raised won't reach the target.  (This explicit
passing of raised capabilities is how we in fact encode Java stack
inspection in one of our papers on the topic).  If you wanted to
directly program with this kind of security, it would mean every method
for which you wished to support this kind of security would need an
additional argument which was the current security context.  Java
security architecture can be viewed as a system which does all this
bookkeeping for free for you and saves your code from going ugly.

BTW, one other feature of the Java model is that a temporary privelege
cannot actually be used by the grantee for their own purposes: the
grantee cannot have any active records in the stack at stack inspection
time.  One crude model for Java temporary raising of security is as a
capability which times out (expires) when the stack record with the
initial grant is popped.  But, this fails to capture the requirement
that there are no intermediate unprivileged activations on the stack. 
So, there really does seem to be a need to do the full security passing
through all method calls if you want to encode this in a capability framework.

Capabilities are more fundamental in the sense that I don't think they
can be encoded at all in a "reference-free" language.  In terms of
programming language theory, unforgeable references are something quite
fundamental and they have in fact been the #1 stumbling block to
researchers trying to create a "purely mathematical" semantics of
programming languages, one in which functions are described by e.g. set
theory and not by operational definition.

Concluding, I think its pretty clear there is a gap between the two and
the Java model gives something which is hard to get with capabilities. 
Whether this is really something you will want in practice is not
completely clear to me, but it does seem to provide another dimension of
protection, kind of like security guard PLUS the barbed wire fence PLUS
video monitor kind of thing: each is doing something different and
together they provide more security than individually.  Whether the Java
architecture gives enough extra to be worth installing is unclear to me,
esp. if you already have capability-based security in place.

Scott