implementing sandboxes with capabilities

Lex Spoon lex at cc.gatech.edu
Tue Apr 11 22:25:25 UTC 2000


Wow.  Okay.  That said....


> 	We can solve this problem!   Every compile checks the subclass tree
> of the class it is installing in.  For each "Proxy" subclass, if that
> selector was not available before, it compiles a stub with an error message
> in it.

Okay, this works as well.  Note, though, there will be some proxies
that aren't just a restricted form of some other class.  (Maybe "proxy"
isn't the best term).  For example, you might have a queue of input
MorphicEvents, which doesn't correspond to any object in the system
thus far.  But for things like ClassProxy's or BlockProxy's, making it
a subclass should be fine.  (So long as you stub out all the disallowed
methods, of course!).



> ( )  I agree with Andreas that we should try to avoid having a "Shared
> Immutables" space.  How about if SmallInteger and Character simply can't do
> very much?  The SandCastle user would have access to the *real* chatacters
> and integers, but can't do anything bad with them.  SmallInteger and
> Character, and perhaps their superclasses, are Proxy classes.  All
> destructive methods in SmallInteger and SmallInteger class are removed.
> None of the truly useful methods in SmallInteger need to cause harm.  (Can
> you think of a counter example?)  (Magnitude superclass would be blocked,
> but the user does not need to send #superclass.)


I think we all agree here, except on terminology.  I'd like to be able to
label all objects as being exactly one of the following:

	1. a proxy
	2. in the main image
	3. in the sandbox

Well, $a is going to be in both the sandbox and the main image at
once.  How do you describe this situation?  Well, how about a
4th category called "shared immutables".

The rules that things in each 4 categories must obey are different.

Furthermore, the rules for proxies and for shared immutables are the
strictest, so lets try and not have too many of them.  Ideally, once
the system is in place, regular programmers no longer have to think
much about it.  Just like a building with good security: you just
mindlessly swipe your card whenever you get to a locked door, and you
only think about it when the door doesn't open.


> 
> The idea here is that the Proxy classes control access to all methods that
> Sandbox code can call.  If a ProxyRectangle class allows a selector (does
> not block it with a stub), the real method for that selector is run in the
> superclass, Rectangle.  Further up in the system, in powerful primitives,
> and classes like FileStream, checks do not have to be made.  If a process
> in a Sandbox ever gets there, is must be via an approved call to a Proxy
> class.


I was hoping that most objects won't *need* a proxy.  Rectangle, as a
good example, can probably be left as is.  If someone makes a screwed
up rectangle, fine.  They'll have a screwed up rectangle, but this
doesn't seem to harm anything.  The proxies will just have to check any
rectangle that is passed as an argument, to make sure it is well
formed.  It is only for classes that are used at the border between two
spaces, that you need to implement a proxy.

The reason I want to avoid them, is that proxies are extremely
restricted.  "Sandbox safe" classes are also restricted, but
they don't have to avoid passing pointers across them.  Most
classes in the image ought to be sandbox safe already.  It's
only classes that define new primitives, or which access globals,
which need to be hidden behind a proxy, or just plain hidden
completely.



> 
> When the compiler is making methods for a class in the SandCastle, the name
> scope is very restricted.  We already have this working in Environments.

Right with ya!  For example, the set of "globals" in this compiler
should actually be a set of proxies that are initially available.
Also, thisContext should probably be removed, and inlining of #class and
maybe a few other methods should be turned off.


> 
> How about this assertion:  Every object in a Sandbox is either an instance
> of a Proxy class, or an instance of a class defined in the Sandbox.  A
> SandCastle can do *any* perform:.  It can make up any selector and send it
> to any object it gets its hands on.  But, of course, the selector won't do
> anything unless a Proxy class defines it.  Each object is a bundle of
> capabilities.  No further mechanism is needed.

Or, it is an instance of a "sandbox safe" class.  I'm thinking there
should be a tool for verifying whether a class is sandbox safe or not.
Looked at another way, we need a special compiler for classes that
are intended to be sandbox safe.  That compiler would, for example,
disallow globals by default....  (Hey, globals are bad style anyway,
right? :))


Additionally, the invariant should include restrictions on what objects
point to which through instance variables:
	
	- an in-sandbox object may not point to a main-image object,
	  and vice versa

	- a shared immutable can only point to a shared immutable

	- notably, a proxy can point to or be pointed to by anything
	  (except that immutables can't point to a proxy)


Incidentally, #perform: ought to be okay to leave around.  If they
can already do "x foo", why not let them also do "x perform: #foo".
Just so long as the perform primitive properly deals with odd arguments
being passed into it!



-Lex





More information about the Squeak-dev mailing list