However much we may dislike the concept of the reveal operator, we need a solution to the problem created by the following excellent feature of E:
In E, an object does not know--and does not care--whether it is on the receiving end of a call or a send. The object accepts the message, processes, and burps out whatever result is appropriate, blithely unaware of the "distance" from the invoking object. As a result, I have never yet had a bug in the receiving end of a distributed computation.
However, this also means that the value returned from a computation is always a capability at risk of being sent off into the far distance. In the absence of a reveal operation, in the presence of a computation that has no particular return value, E's default behavior (of returning whatever happened to be the result of the last operation) is a security breach. This seems inappropriate for a language with the goal of allowing secure computation.
I became excited about this problem before anyone else did because I was doing visual inspections of all my objects-exposed-across-the-wire to make sure I had "null" as the last line for methods with no return value. It was tedious and error prone. I told markm he needed to stop returning values by default. He ignored me for reasons akin to chip's. Then the following happened:
In a file transfer program I was writing, I was getting these mysterious thrown exceptions in my logs. My computation was running along just peachy, so I didn't worry about it overly much--hey, if it works, and no one is paying you big bucks to make it perfect, that's the way it goes.
One day the exceptions stopped being thrown. About the same time, markm expressed surprise that I was doing file transfer because there had been a bug in E that prevented java file objects from proxying correctly. I said I hadn't noticed because I wasn't sending java file objects, I was sending wrappers for file objects. We shortly realized that what had been happening was, I was accidentally sending a real file object over the line at the end of a void computation--that accidental return of a file object was throwing the exception.
Folks, if there hadn't been a bug in E proxies, causing a spare exception that caused markm to make the reveal operation explicit, that security breach would still be a part of my program, and I still wouldn't know it. This in a program ridiculously smaller than what we hope to be writing securely. Scary.
It is really not acceptable for the default behavior of a capability language to be a security breach. Swaddle this problem in as many development standards and visual inspections and coding conventions as you want, and it still just isn't acceptable. We need to save our security auditing strength for the real problems, not for default behavior accidents.
From: Chip Morningstar <firstname.lastname@example.org> To: email@example.com <firstname.lastname@example.org> Date: Thursday, September 23, 1999 4:12 PM Subject: Some thoughts on the 'reveal' operator
>I understand that this is trying to make revelation explicit, presumably so
>that it becomes a deliberate act (for example, so that a function does not
>inadvertantly reveal information that was not meant to be revealed, simply
>because that information happened to be the last thing computed). That's a
>laudable goal, but I suspect the mechanism will prove cumbersome. Falling
>on the custom of using the value of the last expression in a block as the
>of the block seems to me a more pragmatic design. If we need to have an
>explicit value that denotes a non-result for the "I'm not really returning
>anything" case, that's OK with me.