implementing sandboxes with capabilities

Robert Withers withers at vnet.net
Wed Apr 12 05:53:30 UTC 2000


Sorry for the length...We are crossing the object-class barrier so we
involve the ObjectMemory and the Compiler, and I'm kinda confused... ;-)

Lex Spoon wrote:
> 
> Robert Withers <withers at vnet.net> wrote:
> >> There are two major nexii of control, that we need to handle, and I am
> > continually getting them confused.  One nexus is to disallow any
> > navigation across an edge in the stateful graph of objects (bindings),
> > yet we still need to have a binding.  The other is lookup of a selector
> > during a msg send.  This is where the granting of capabilities would be
> > implemented.
> >
> 
> I think we have different schemes in mind.  I don't think we need to
> change the way method lookup works.  Either an object responds to a
> message, or it doesn't.  That's all you need to implement a capability.

Phew!  This is thin ice for me, Lex. :) I don't know that much about
OSes other than using, a little admin, and some reading.  I did look
into Merlin several years back.  EROS is a blank.   The goal *is*
providing the base structure to do this. <grin>

The problem I have with this is how do we allow creation of a mutable
class inside of the local space (unproxied) and still restrict
capability?  Can we do this?  Well we can do whatever we have the
talent, time and enthusiasm for.  Could we do it in a x-dialect way?  We
would have to intecept the message #class but I believe that that is
inlined in the VM.  Therefore we need to proxy all restricted behavior
objects.

Another issue, mentioned previously, is if we allow certain mutable
objects locally, with full behavior, we would need to disable #become:
in the VM.

If Namespaces partition the semantic space, then ObjectMemorySpaces
(SandCastles) would partition the instance space.  The interesting thing
to me is that Namespaces are used at compile time to resolve literal
scope, while ObjectMemory is used at runtime to manage live objects.  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.  If fact, we
could ship EvaluableClosures which could cache at the usage location for
mobile code.

Ok, all this is blue sky stuff, but the base of that capability (:-0) is
to define the topology of ObjectMemory partitions, and analyze how we
control message sends to instances.  It seems that a way to define the
topology is based on visibility of objects.  So...

> > Local Elements
In my space
> > nonlocal immutable elements.
Direct pointer
> > nonlocal mutable elements.  (some of which are Behavior objects)
Proxied
> 
> I think you can actually avoid having global mutable elements.  For
> example, instead of allowing direct access to behaviors, you provide
> *proxies* to behaviors.  The behaviors themselves only exist in a single
> space.  (The "main image" space in the basic sand castles application)

I hadn't assigned these things to spaces yet, so I agree with you,
Global Mutable = BAD.  The nonlocal immutable are global, but the
nonlocal mutable are proxied.  I hadn't placed these in a topology yet
(I don't think - these math tricks are..well..tricks!).  Let's create
the basic topology of spaces... 
 
> > Let us create a minimal solution with the most flexibility.  The way to
> > do this may be a construction of a tree of spaces which hold Objects,
> 
> You seem to be describing what the topology of the spaces will look
> like.  I haven't been worrying about that too much, and as far as I can
> tell, the basic framework can ignore it.  With the right framework, you
> can later build any kind of topology on top of it that you like.
> 
> For example, in the basic shipping sand castles case, I think you only
> need 4 classifications of objects:
> 
>         1. Shared immutables.
>         2. main image objects.
>         3. sandbox objects.
>         4. proxies between the main image and the sandbox.

You just created a topology, right?  (and I am seeing your BookMorph) 
The first thing is that the global immutable objects are the Universal
set.  It defines the root space that is the image.  All other spaces are
subspaces.   There are several other Globals that are mutable, but we
really don't want unproxied access to them, so they are in a SystemSpace
(of which we may have several).  This may require a recompile of course.

> Four seems like few enough to just wire the thing together by hand.  And
> the scheme doesn't *stop* you from having something more general on top
> of it.
> 
> > If this can be done by subclassing the Surrogate from ProtoObject or
> > creating another root from #nil then great.  I am trying to consider a
> > cross-dialect solution.  The point in having a binding is to send
> > messages to it, right?  Therefore, the alternative approach is to
> > decouple a binding and stick a pumped msg queue in between.  Not the
> > easiest solution as there are pointer management problems like GC and
> > serialization/synchronization problems.
> 
> Ah, you want to automate the proxy generation?  (proxy being an object
> at the border of two spaces)  I've taken the opposite view.  Proxies are
> where security policies get implemented.  Proxies are the place where
> humans show their design skills and engineer a new security scheme.
> Proxies would rarely, in my scheme, just accept a message and forward
> blindly to the other side.

This is the crux of the matter.  I don't want to blindly forward them
either, but how do we install a capability?  Proxies *are* where _most_
of the security is implemented, but we may want a DCE style 3rd party
security service which would require token security that contacts an
agent.  

How do we deny the creation of a new Process object and then setting the
priority to #highIOPriority?  We probably want to allow forking, but we
need to restrict some of the methods.  Do we proxy it?  Sure, but that's
a snake pit.

Who holds restricted capability and how do we ensure that there is a
solid barrier?

> >From my view, proxies are hard, and should be kept to a minimum because
> of this.  There wouldn't be much automation involved, just careful
> programming.

Yes they are. :)  I feel like I just went in a circle...   We want
immediate references, but we want to restrict the behavior.  Perhaps
this is why Self went to a prototype model?
 
> >
> > I would like to think of this from a multiuser standpoint.  There should
> > be no reason that all of us couldn't be processing, in a protected way,
> > in one image.  My concerns are that we rush this without thinking that
> > generality through.  I think having multiple Proxy Subclasses is smelly
> > and may well cause big problems.   A big problem regardless, will be the
> > administration of capabilities.  Another question is what does it mean
> > to pass a surrogate to another space?   All arguments to a msgSend
> > should transform to the appropriate Surrogate (or direct pointer).  The
> > return should also map.
> >
> 
> Hey, making it OS-like sounds good to me :)  It's a lot of work, though.
>  I think you'd want some form of internal email and/or instant

That was the use of the pumped queues, which are ports...and not my idea
either, David Caster (TFEI)

> messaging.  Also, you probably want to give each user a private "file"
> space to store objects in.  Probably you want to make Squeak checkpoint

A subspace to the users space..

> somehow, perhaps by doing a periodic snapshot, or perhaps by having a
> background checkpointing-thread like in EROS and many other systems.

What is the use of the checkpointing thread?  Time-slicing?

> Also, you probably want to give each user a *public* space, so they can
> publish objects and messages and whatever.  And maybe you want these

Another subspace but with a publishing service..

> object-spaces to be hierarchical, like a file system.

Right...The space topology.

> 
> Anyway, I could well be missing something, but I don't see any
> particular hindrances in making a secure multi-user Squeak system.  It's

The problem is the Capability restriction and how to build a perfect
fence.  Instance based overriding of a method and interception of a
message send to that method would do it.     Is that what you are
considering or have I complicated the problem?  How do we do that? ( I
ask for the 4th time or some nonsense...sorry)

> mostly just a lot of mini-applications you'd have to write before the
> thing started really looking like an OS.  (But what a cool OS you could
> write, where all users have a graphics device that is in the same
> ObjectMemory as yours, and where email is done through message sends!)

Well, I don't know about shared graphics devices, but if we view the
ObjectMemory as a WorldWideObjectMemory then perhaps... ;-)   But email
with message sends would be nice.  LindaTalk plays a role in here
somewhere, probably as both a Nameservice and as a Resource manager.

Nonetheless, this is a *very* interesting direction...
Rob

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





More information about the Squeak-dev mailing list