Comments on Lex's "Object as Capabilities in Squeak"

Robert Withers rwithers12 at
Thu Jan 30 07:27:54 UTC 2003

Mark, I would like to thank you for this significant commitment you  
have made in engaging us with your ideas.

My goals have been to learn some of E's infrastructure, and to start  
building towards multi-user squeak and mobile-code.   It looks like  
this fits at your second level of ambition.  It would not surprise me  
if this is the level Croquet is reaching for.

However, I like the challenge and reward of your fourth level of  
ambition.  It requires several orders of magnitude greater of a  
community commitment.  If I understand correctly, with the benefit of  
having read on your site about financial capabilities, privileged  
security abstractions allows for trusted "arbitrage" objects (my  
terminology), which people could *really* trust.  Here is where some of  
these ideas are published  
(  That is a very  
valuable feature.

As you ask in your mail, what would we lose from Squeak, or be willing  
to lose, to do these things?  I think we need our tool environment and  
the debugger.  We need to have on-the-fly coding and state  
manipulation, inside the debugger and inspector.  We should be able to  
turn down security, if authorized, to debug between secure components.   
If the user is not authorized to debug into a component, perhaps the  
execution stack inside of that component could be pickled for an  
authorized user to replay through the debugger, at a later time.   
Without these kinds of features, and certainly others I don't know  
about or can't express, it may turn out to be a very hard compromise.

We would need to secure the stack.

"No way Squeakers could do that"  I hear.

"Who knows.  let's at least find out", I respond.


On Wednesday, January 29, 2003, at 05:37 PM, Mark S. Miller wrote:

> [cross-posted to squeak-dev and e-lang]
> In rereading Lex's paper, Anthony's paper, and the Squeak-E thread on
> squeak-dev, there's a lot to say. I'm tempted to just jump right in  
> and try
> to talk you guys out of dynamic scoping, just as Norm talked Dean and  
> I out
> of it in the Joule-design days. I do think this is the most important
> remaining issue (though not the last one), but I think I'll instead  
> build up
> to it slowly. It took Norm a long time to convince us, even when we  
> already
> had a large base of common premises. I think I should first see what
> premises we all do have in common, and what premises we can come to  
> have in
> common. I will start by commenting on Lex's paper. From there, I  
> expect to
> go on to Anthony's, and then to the email thread.
> On first reading Lex's paper, I assumed that we were all trying to  
> solve the
> same set of problems, and that Lex (and squeak-dev) has not yet  
> realized the
> incompatibility costs of addressing these. On rereading Lex's paper, I  
> think
> this is still probably true, but it strikes me that y'all may in fact  
> only
> be interested in a genuinely less challenging subset of these  
> problems, in
> which case y'all can plausibly address these at a much lower  
> incompatibility
> cost. In any case, none of us can make informed choices until we  
> understand
> what these tradeoffs are. This will be new exploration for me too, as  
> so far
> I've mostly only thought about the more complete problem.
> All unattributed ">"-style quotes are taken from Lex's "Objects as
> Capabilities in Squeak", Aug2000 version, at
> .
> For a first attempt at a taxonomy, let's try the following four levels  
> of
> ambition:
> 1) Applet-like security:
>> In order to widely share Squeak pages across the Internet, it will be
>> necessary to engineer a safe display environment--a sandbox--for such  
>> pages.
> I've never heard of "Squeak pages" before. (My apologies again for my
> ignorance of Smalltalks post PPS2.5.) However, from the meaning I'm
> guessing, this sounds like a statement of purpose that could as well  
> have
> been stated for Java applets. I would characterize this as:
> Instantiate safe "mobile" code. The applet-like instance can render  
> into its
> window, receive ui events and interact with the user, but cannot  
> exercise
> any of the user's authority nor modify any of the user's persistent  
> state --
> beyond the state understood to be part of the applet-like instance  
> itself.
> The problem with applets is, they're useless. That's why you don't
> hardly see any. Their uselessness is precisely derived from a) their
> starting position of lack of authority (good), and b) the inability to
> incrementally and dynamically authorize them--well after they're
> instantiated--to do some useful job (bad). (See #2 below.)
> For those seeking only this level of ambition, I see nothing at all  
> wrong
> with the mechanisms Lex proposes. (This is *not* to imply that these
> mechanisms aren't fine at higher ambition levels, or to fault Lex's  
> paper
> for not articulating a more extreme goal-set. It's taken me decades to  
> go
> from working on these problems to being able to explain what problems  
> I'm
> solving, and I still feel like I haven't reached the halfway point on  
> that
> journey.) I point this out so we can keep track of  
> ambition-architecture
> correspondences as we go.
> When I say "I see nothing wrong", I'm referring specifically to Lex's
> paper. In particular, please don't take this remark as an endorsement  
> of
> dynamic scoping (currently being discussed on squeak-dev) even for this
> first level of ambition. The paper transforms globals into per-process
> variables, where a process serves much the same function as a  
> ClassLoader
> unit (the ClassLoader, all the classes loaded by that loader, and all
> instances of those classes) in Java's applet architecture. Either of  
> these
> mechanisms would be candidates for the least incompatible change to
> Smalltalk in order to rescue "globals", rather than replace them. If
> relevant objects are partitioned between such processes (as I take Lex  
> to be
> mostly trying to do), then the two mechanisms may even be close to
> equivalent. If y'all's ambitions really do stop here, it would be good  
> to
> argue their relative merits, but I'm hoping we won't need this  
> argument.
> (If the relevant objects cannot be so partitioned, such that the same  
> object
> can be accessed from multiple such processes, then I would indeed  
> argue,
> even for this ambitiion level, that process-scoping is wrong while  
> loader
> scoping still looks acceptable. But I'll wait on that argument until it
> proves necessary.)
> OTOH, Dynamic scoping goes well beyond trying to preserve  
> compatibility in
> order to rescue old code, and instead introduces a new linguistic  
> concept
> substantially more complicated and questionable that  
> per-process-scoping or
> loader-scoping, solves no further security problems, and moves Squeak  
> away
> from the idea of object oriented programming. But I'm getting ahead of
> myself again.
> 2) Caplet-like security, one level deep:
> As safe as applets and as useful and usable as applications.
> goldenTriangle.html
> Lex's reference to "pages" and the text spent on UI access leads one to
> expect that the user is able to operate the ui of untrusted code --
> applet-like so far. In order to get beyond the sterile uselessness of
> untrusted Java applets, the user needs to be able to grant a  
> caplet-like
> instance further specific authorities, as appropriate in order for the
> caplet to do some useful job on behalf of the user.
> Authorization must happen by intuitive user interface actions,  
> enabling the
> user to "naturally" (without thinking they're thinking about it)  
> maintain a
> model in their heads on the bounds of authority they've granted to  
> different
> caplets, so they can naturally reason about the bounds on risk to  
> themselves
> when considering another act of authorization.
> See for an elaboration of these
> principles, and for  
> a
> concrete system with UI (CapDesk) that implements 8 out of 10 of these
> principles. (Crucially, CapDesk turns the UI into a capability system  
> using
> the same philosophy we're applying at the language level: turn each  
> act of
> designation into also being the corresponding naturally-implied act of
> authorization. The user does essentially the same things he normally  
> does.
> These user-interface actions are now understood to also have the  
> security
> meaning that one would naturally expect. This is a bold claim. Look at  
> the
> pages to see the system in action.)
> The above systems go out of their way to look conventional while  
> obeying
> these principles. It would be a very different, and quite exciting,
> investigation to apply these principles to Croquet.
> Before speaking to what any of this might have to do with the  
> architectural
> issues being discussed, I'll first wait to get a sense of whether  
> y'all are
> interested in pursuing these overall goals.
> 3) Privileged security abstractions
> 4) Unprivileged security abstractions
> By a "Security abstraction" I mean something like the revocable  
> forwarder
> shown as Figure 6 on page 6 of  
> .
> Such a security abstraction often stands between several different
> interests, receiving and manipulating authority on behalf of each of  
> them.
> Such abstractions are also "deputies", as explained starting on page  
> 11 of
> the same paper.
> Modern CPUs have a "privileged mode" and an unprivileged, or "user"  
> mode.
> E is built on Java. Java code in the E implementation is like code run  
> on
> the privileged instruction set, and E code is "user code". Lex has a  
> similar
> distinction between "privileged" and "unprivileged" Smalltalk code,  
> and I
> suspect he has to. No matter how similar these are made, they  
> constitute two
> separate languages which need two separate names. Let's call then  
> "Squeak"
> and "SafeSqueak". Unconverted legacy code that remains in the image is
> Squeak code, all of which is in the TCB.
> By "privileged" security abstractions, I'm attempting to define an
> intermediate level of ambition that may require less principled  
> support.
> The issue is, how complete a language is SafeSqueak? It's easy to make  
> it
> expressive enough to do applet-like things (#1 above). It's next  
> easiest to
> also enable it to accept and use authorizations reified as
> capabilities-as-objects (in support of #2). But is the system such that
> SafeSqueak objects may find themselves between other SafeSqueak  
> objects,
> each representing different interests? Is SafeSqueak a good language
> for writing security abstractions as deputies, in order to bring about
> cooperation without responsibility in such a system?
> If the answers are yes, then we're in #4. Otherwise, different  
> unprivileged
> interests may still be represented by SafeSqueak code, but the security
> abstractions that stand between these interests are all Squeak code.  
> In this
> case, we're in #3. To determine which of these apply, a good exercise  
> is to
> try to rewrite the money example from
> capabilities.html#simple-money
> in SafeSqueak. I would like to see Squeak evolve into a system that can
> support #4. I would hope y'all do as well. Only with #4 can SafeSqueak  
> be a
> self-contained language, and Squeak become a shrinking legacy.
> A note on consensus:
> Above I've repeatedly talked about finding out what "y'all" want or  
> believe.
> I don't imagine y'all are a collective, any more than I imagine e-lang  
> is.
> I'm just referring to the sense of the community that I hope to gather  
> from
> the reactions.
> **********************************************************************
> In the section
>> The ObjectInspector Capability
> a set of methods are listed. #realBlockFor: is missing, as it is  
> mentioned in
> the section
>> The ObjectInspector Capability
> as
>> realBlock := ObjectInspector realBlockFor: aRestrictedBlock
> The ObjectInspector design seems sound, as a super-powerful part of  
> the TCB,
> to be closely held within the TCB, in order to build things like  
> privileged
> debuggers. (Unprivileged debuggers are hard, even in #4 architecture!  
> KeyKOS
> and EROS do it. E does not.)
> It seems to me that ObjectInspector can be refactored in a way that  
> would
> make it both more convenient, and would naturally subdivide authority,
> simply by currying it. I assume that the listed methods of  
> ObjectInspector
> are class methods, as shown by the above quoted use. Let's say that all
> these were instead instance methods, and that ObjectInspector instead  
> had
> one instance variable and one "new:" class method. Then, instead of  
> writing
>     x := ObjectInspector instVatOf: obj at: i
> you'd write:
>     x := (ObjectInspector new: obj) at: i
> The cool thing is that (ObjectInspector new: obj) evaluates to an  
> object
> giving encapsulation-breaking, meta-level access only to the state of  
> object
> "obj" rather than the system as a whole. This is a small but crucial  
> step
> toward non-privileged debuggers, if you wish to get there eventually.
> *******************************
> In the section on Literals, you seem to use immutable and read-only as
> synonyms. I find this confusing. To me, "read-only" means I can  
> observe the
> current state but modify it. It doesn't mean the state won't change.  
> And if
> the state to which I have read-only access does change, I expect to be  
> able
> to observe the new state.
> Do you indeed mean "immutable" everywhere you say "read-only"?
> ******************************
> The section "Dynamic Variable" seems to be to explain only per-process
> variables. Is this right?
> Could someone explain about "World"?
> This section refers to "methods that are marked as privileged". Even  
> after
> reading the later section that explains this, I didn't feel like I
> understood how this marking happens, or how the authority to do this  
> marking
> is controlled.
>> are still be able to access variables
> Bad "be"
> Can the same dynamic-variable-using instance be invoked from different
> processes (causing different bindings of the same use-occurrence of  
> the same
> variable), or are dynamic-variable-using instance partitioned among the
> processes that can invoke them. Unfortunately, I suspect it's the  
> first, but
> I'll wait to find out before arguing against it.
> ************************************
>> Whenever code is loaded from untrusted sources, it should be loaded  
>> into
>> unprivileged methods.
> I'm not sure how to read this. If the code includes methods that were
> written assuming they would run privileged, what happens?
>> Processes with direct access to
> I don't understand what this means, but it alarms me. In a capability
> system, we should be speaking only of objects having access to other
> objects. I know that Processes are objects, which is good, but I don't  
> think
> this accounts for what you mean.
> *****************************
> Are restricted classes (as implemented by the restricting proxy)  
> read-only?
> (I mean, genuinely read-only, not immutable.) I think they should be.
>> In particular, many class methods return "self"
> This reminded me that Smalltalk methods by default return self. E had a
> different but similarly dangerous policy. We found to our terror that  
> this
> was a pervasive source of accidental security holes in our code, very  
> much
> along the lines of the specific security hole you found with classes.  
> Rather
> than making a custom repair for each individual case, I fear that  
> you'll
> find you'll want returns-to-SafeSqueak to return null, rather than  
> self, by
> default. This is the first issue I've encountered that makes Java  
> easier to
> tame than Squeak. In Java, methods are void return by "default".  
> ("default"
> is a funny word. It's still explicit, but is the path of least  
> resistance.)
>> required to allow access one of these
> Typo: insert "to"
> **************************
>> An incomplete list of such methods is the following:
> I would be very interested to see the complete list of methods on  
> Class,
> ClassDescription, Behavior, and Object that you consider safe. It's  
> much
> more important to review the list of what's allowed than the list of  
> what's
> disallowed (though you made the right choice of which to list for the  
> paper).
> I don't understand why you allow instaVarAt: and instVatAt:put: on
> non-proxies? Does this include non-proxies written in SafeSqueak?
> I completely did not understand the section "Characters and Symbols",
> probably because of my ignorance of modern Smalltalks. Could you  
> expand?
> *********************
>> This proxy might or might not immediately install the cursor as  
>> requested,
>> depending on the precise security policy that is being implemented.
> Implemented by whom, how? This is the first I've seen of "security  
> policy"
> used this way.
> ********************
> I would hope to convince you that shared-memory multi-threading, locks,
> semaphores and such should not be part of SafeSqueak. But, scoping and
> partitioning issues aside, this is a mostly separate discussion we can  
> leave
> till another time.
> ********************
> You don't actually explain what the issue is with Exceptions.
> ******************
>> In particular, the following primitives should be disabled:
>> * instVarAt: and instVarAt:put:, because they allow directly breaking
>>  confinement
>> * at:, basicAt:, at:put:, and basicAt:put:, if the proxy has indexed  
>> fields,
>>  because they would allow directly breaking confinement
> I think I understand the others, but what's the problem with #at: and  
> #at:put: ?
>> Additionally, #shallowCopy and #clone make revocation much more  
>> difficult;
>> thus, they should most likely be overridden to return the receiver  
>> instead
>> of returning a true copy.
> If you can't support their contract (and indeed you can't), then  
> shouldn't
> you just suppress them?
>> Note that all non-primitive methods from class Object may be safely  
>> left
>> accessible. Since such code must consist of message sends between
>> parameters, self, and globals, user code could emulate the code even  
>> it it
>> were disabled, and so disabling such methods gives no gain in  
>> security.
> Are all the globals accessible from methods on Object necessarily  
> accessible
> by both callers and subclasses?
> ********************************
>> A primary advantage of the submemories approach is that there is no  
>> need to
>> add a special kind of cross-memory oop
> Given the stated purpose of submemories, you need to be able to  
> reclaim a
> submemory without being able to reclaim the parent memory. This means  
> that
> oops from the parent into the sub need to spontaneously seem to become  
> some
> innocuous object (like null) when this happens. I think you will find
> support for this hard at fine-grain. E supports this only between vats,
> where there's an enforced indirection through intermediate objects  
> anyway,
> and where the possibility of partition is part of the semantics anyway.
> In any case, I recommend postponing further worry about resource  
> controls
> and denial of service until these other issues settle down.
> ----------------------------------------
> Text by me above is hereby placed in the public domain
>         Cheers,
>         --MarkM

More information about the Squeak-dev mailing list