[E-Lang] Re: Old Security Myths Continue to Mislead

Chip Morningstar chip@fudco.com
Sun, 5 Aug 2001 01:45:30 -0700 (PDT)


Jonathan requests:
>... I would prefer that the "Original E"
>team discuss here their experiences with the performance of pervasively used
>object proxies. That would be relevant, and it might help Dan's group in the
>process.

I don't recall that we ever did any serious measurements of this overhead
(although perhaps MarkM can correct me on this point -- my memory isn't as good
as I remember it used to be).  At least, I don't see anything in my records to
indicate that we did that.  I certainly don't recall it ever registering in any
of the profiling we did when looking for performance bottlenecks in general.
Actually, I doubt it would ever have occurred to us that this might be a
significant source of overhead.  Even now that the issue has been raised, I
find the suggestion somewhat bizarre.

Mainly this was because the overhead of mediating proxies was basically
irrelevant for structural reasons.  Certainly it *would* be significant if you
were doing it with every object reference, but doing it with every object
reference would just be silly. Basically, this mediator pattern mostly cropped
up in two kinds of places:

1) when exporting capabilities to external agents (i.e., entities on a
   different computer on the network). In this case the overhead of one more
   method call on a message pass is lost in the noise given the base cost of
   sending a message over the net in the first place.

2) when wrapping a safe interface around one of Java's very unsafe interfaces
   to various system resource (e.g., files). In this case you are paying the
   cost of an intermediary object *anyway*. And in Java coding I've found that
   you fairly often want to wrap these resources in cleaner interfaces anyway,
   just to make your internals more straightforward, so I don't see that using
   a capability pattern adds much additional cost. Revocability, in particular,
   adds just the cost of a single conditional branch to the overhead.

In theory you might expect to use the mediator pattern when dealing with
relations between mutually suspicious objects in a common address space, but in
practice this never really happened very much. The reason is because in our
world a capability is just an object reference. Since the language semantics
make it impossible to break encapsulation, you are almost always safe just
creating and passing an object which represents exactly (and only) the
authority necessary for whatever operation it is being passed for (which in
good O-O programming practice is what you would do anyway). Once again, the
overhead is not significant beyond what you are already doing. And there is a
great performance *benefit* in never having to stop and ask "is this operation
OK?".

Note that the requirement for an intermediary only arises when there is an
existing object that doesn't intrinsically support the kinds of security
controls that you want it to have. The two cases above are exactly this:
objects executing in environments outside the compartment you trust to obey the
rules and legacy objects with bad interfaces.  But if you are programming
within the capability model using something like E, there is rarely a need for
an intermediary object. Generally the nature of the capability will determine
whether it needs to be, e.g., revocable or not.  If it needs this, you build it
into the object; no additional intermediary is required. Note also that at this
point you have the ability to be arbitrarily flexible in your security policy;
you are not limited to the controls available via an external "security
manager" or some other broken piece of foolishness like that (this last
referring not to what Dan is doing, which I know nothing about, but to what
Java tries to do).

Chip