implementing sandboxes with capabilities

Robert Withers withers at vnet.net
Wed Apr 12 18:51:06 UTC 2000


Well, I'll give this a shot, but the standard disclaimers apply...

Henrik Gedenryd wrote:
> 
> Lex Spoon wrote:
> 
> > 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
> 
> Lex, I may just be numb here, so that this is not an issue, but how do you
> know whether an object belongs to 2 or 3?
> 
> Say that a type 3 object is an instance of a class where at least one method
> references a global. What spot in this scheme prevents a type 3 object from
> executing this method, or at least, from gaining access to that global eg.
> by assigning it to one of its instvars? There are several ways to solve this
> of course, but I sense that I may simply be missing something.

It seems like we need a SandCastle aware compiler to Proxy all global
bindings?  This would include the creation of an Environment, specific
to a SandCastle, which would have all Globals proxied into that
Environment. (since Globals aren't in the UniversalSpace, they are in a
GlobalSystemSubSpace - I guess this requires a BookMorph!).

> This seems to coincide with Lex's issue of detecting that a proxy method
> doesn't pass (return) an object across the boundary. How do you check this?

All performs should check arguments and return values.  The trick is
going to be intercepting all performs...
 
> Re. Proxies:
> 
> I see more potential trouble with proxies as subclasses, than as separate
> pseudo-behaviors that a) contain a set or MessageDictionary with the allowed
> selectors, and b) just forward all these messages to the actual non-safe
> object. In this way, the proxy has no instvars at all--potentially not even
> one pointing to the actual object, if there is some kind of primitive that
> accesses a dictionary that maps proxies to their actual objects; the same
> primitive, presumably, that forwards the messages contained in the allowed
> set.

I really hope that we can do this without a primative at the moment (for
portability).
 
> This is equivalent to an SOP subject (ie. which sees only a subpart of an
> object). If we had aspects/perspectives, then a proxy would simply be a
> reference to a 'safe' perspective on the entire object.

Are there any implementations of perspectives out there?  I downloaded
the aopst stuff to look into Aspect-Oriented Programming...
 
> Re. Classes, and restricting accesses to classes:
> 
> > A class defined in the Sandbox must be the direct subclass of a class that
> > is either defined in the Sandbox or is a Proxy class.
> 
> Isn't it enough to keep in mind that a class is an object too? In other
> words, if an (eg. sandboxed) object can get hold of a reference to a class,
> then it can subclass it--and only some class objects are made available to a
> sandbox. In this way, the capabilities mechanism itself solves the class
> issue.

What about #class and #superclass?  We need to break inlining if
possible.
 
> By extension, a sandbox would be an environment with its own namespace
> dictionary instead of Smalltalk, and objects therein would thus only have
> access to the objects in this dictionary.

If we view the namespace environments as orthogonal to the object space
topology, then maybe we could define visability differently.  In the
space topology, a subspace can see unfiltered to the parent, but the
parent has a filtered view into a subspace.  On the Environment side
this seems flipped to me:  A subspace can only see a filtered view up to
the Globals but the root Environment can see unfiltered into Subspaces. 
This would mean that the GlobalRootEnvironment would be Proxied in the
GlobalRootObjectSpace.  Metacircular fixedpoint.  :)

I am viewing the reference to a thing in a slot differently than the
Binding to a thing in a context.  Is this the correct view?
 
> Robert Withers wrote:
> 
> > In general, we want
> > to partition the image into multiple subspaces.
> 
> > Let us create a minimal solution with the most flexibility.
> 
> I'm entirely with you. My comment about the relation to SOP/AOP was made
> with this intention.

Cool. :-)  

> > Those elements which are immutable or local should be direct bindings,
> > however the nonlocal elements should be represented in the local space
> > as a surrogate (proxy), which can control nonlocal access to the real
> > thing.
> 
> With capabilities, we would be *very* close to a completely "separated
> segments"/whatever distributed solution, or what I would call 'second-order
> objects': I see a sandbox (or a current running VM/image) as a second-order
> object that protects its insides from the outside, and only allows for
> message-passing across the boundary. With the solution you suggest, we would
> need to add very little to have location-independent processing, ie. not
> needing to care where an object resides to message it (in another namespace,
> sandbox, on another processor, in its own protected memory segment, or
> across the internet). Like having namespaces on super-steroids.

Perhaps with a discovery service of some kind.  Locating a thing doesn't
seem to be as much of a problem as isolating a thing.  This may be in my
confusion space; I'm not sure yet.. (mmm a tautology - I'm not sure if I
am confused)
 
> > If
> > we could 1) partition it and 2) manage remote proxies between partitions
> > AND 3) control the message sends to those proxies, then we could define
> > a lot of different types of spaces.  For instance, there is nothing that
> > could stop us from defining a DistributedObjectMemory and have the
> > Proxies manage the GC and faulting/caching of attributes.
> 
> This is what I was thinking of. To me the question seems to be: how tell
> which partition an object belongs to? (This is necessary if we would allow
> objects to refer to 'sibling' objects by name: what namespace to look in?) I
> suggest a variant of the "Soul of a new machine scheme": telling from the
> OOP/memory location. Either we have separate hard adress spaces, so two
> numerical comparisons tell where it resides. Or we do this: currently Squeak
> objects are grouped together, several ones of the same size, in the same
> memory block (I think). If we marked each such block as belonging to a
> certain partition, then all objects in that block would also belong to that
> partition. Each of these schemes have different speed/memory requirement
> profiles, depending on what we would need.


I think that this is an implementation detail, for effeciency, whereas
we really just want to bind/reference to a thing (under system control)
and send messages to it.  We should be able to do this in the image,
darnit!

I am now thinking that we need 2 compilers, the main one is SandCastle
aware, so it can Proxy Global references.  This could modify the way in
which a Global assignment occurs to go through a Proxy method.  We would
need to recompile the entire image.

The other compiler is a ProxyMethodCompiler which is activated upon
capability installation.  There will be a core set of ProtoObject
methods and Behavior methods that we want to recompile for a Proxy. 
#class, #superclass, #become:, and #perform:, #instVarAt:, ... could all
be changed to redirect to the appropriate party.  Whenever any
method/capability gets installed into a Proxy, the ProxyCompiler can
hopefully compile the byte codes to #perform: these core methods without
inlining.  The only ones I am very confused about are #class and
#become:, but that could be that I don't know enough to know I'm
confused!  Can a compiler control these lookups by changing the
bytecodes or does the VM do this without a bytecode telling it too? 
Isn't this the key to the whole Space Mountain?

Can we do this without VM mods?

cheers,
Rob

-- 
--------------------------------------------------
Smalltalking by choice.  Isn't it nice to have one!





More information about the Squeak-dev mailing list