[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Security design [was Re: Security in Self]




Bill Burdick <burdick@ars.rtp.nc.us> wrote:
> I think I have an elegant and efficient way (i.e. no additional overhead to 
> current code) to do exactly what you guys want, and since I'm playing with 
> writing my own implementation (or variant) of Self, I may even get to 
> implement it.  Here's the deal...

I also have an implementation cooking, but it is still in the initial
stage. Maybe we could form a club :-)

> Three levels of security (somewhat analagous to C++): private, secure, and 
> public.
> 
> **Private Slots**
> **Secure Slots**
> **Public Slots**
> 
> I forgot what bytecodes you guys used, but here are the ones the my machine 
> will support (if I have a chance to finish it):
> 
> send(selector, numArgs) ------------- joe message send
> privateSend(selector, numArgs) ------ private keyword
> selfSend(selector, numArgs) --------- implicit send to self
> resend(selector, numArgs, slotNum) -- resend keyword (Smalltalk MI super)
> generalResend(selector, numArgs) ---- resend keyword (CLOS call-next-method)
> return ------------------------------ ^ keyword
> pushLit(lit) ------------------------ a literal in code
> pushSelf ---------------------------- self keyword

Self also has an "extend index" bytecode ( which you might need too ).
The "return" and "pushSelf" bytecodes waste 31 encodings each that
might be put to some use. I have mentioned before that you can get
by without the "pushSelf" bytecode if needed.

> Each slot has three definitions (one for each security level).  By default, 
> all of the definitions are the same.  Programmers can define a different value 
> for each level.  This allows security handling on a per-level basis (a 
> different behavior for each level).
> 
> Private keywords access the first definition of a slot.
> Resends and implicit self sends access the second definition.
> ordinary sends (where the receiver is on the stack) access the third 
> definition.

How interesting! I became worried ( wow! it was over a decade ago :-( )
that Smalltalk's private methods were not private at all and came up
with the idea that each class would have two method dictionaries: one
that was used for most message sends and another that was used for
messages to self. Private methods would only be placed in this
second one. Of course, you could have methods that everyone could
send but self, but that isn't very useful.

You might have each object point to three different maps to apply
my idea to your scheme. Or maybe just have "fat slots" that had
three values and flags associated with each name in a single map.

> I think this addresses all of the points made by Dave and Ian.  It doesn't 
> require knowledge of the sender of the message or much more machinery than 
> there is already.

I am also thinking of a scheme for security in Self, but at the level
of multiple users rather than at the level of catching bugs in
programs. The design objectives were to have a system that was
as simple as possible to use and to understand.

In my system, every object belongs to exactly one other object. Though
the Virtual Machine doesn't care about what these owner objects are,
the programming system would insure that they are some clone of the
"user" object.

All tasks run in the context of a "session", which also belongs to
some user. Objects which belong to the same user work normally in
the session, while other user's objects are read only. This is
enforced by the virtual memory system ( for this to be possible,
a page can only have objects that belong to a single user ).
Though you have permission to read ( and copy ) all of the other
users' objects, you don't have pointers to all of them which
effectively makes some of them hidden. Presently there is no
mechanism to keep you from "forging" pointers to get to those
hidden objects.

Users can become members any number of groups. Groups are actually
normal users that can have their own objects. Any member of the
group has the same permissions as the group itself. Groups cannot
be ( even indirectly ) members of themselves, and so form an
acyclic directed graph. All users are members of the "public"
group and all have "superuser" as a member ( it is probably better
to have a set of less powerful superusers ).

This is the bulk of it. There are many little details, and as I
am not good at security, I am trying to figure out if I missed
something major. It seems that I can get by without a Unix style
"setuid". Take the passwd file for example. In this Self it would
be a Set of users belonging to the superuser and placed in a
public place where everyone can read it. No one can modify it,
but your user object would point to a password object ( encrypted,
so others can read it but it does them no good ) that belongs
to you so you can change it whenever you want without superuser
privileges.

The main problems are:
   1) protection does not happen at the slot level.
   2) a user is not protected from himself ( to catch bugs or
      prevent accidents ).
   3) hidden objects are not really secure.

The best solution for 1 and 2 might be what has been discussed here
so far. One idea I have for 2 and 3 is to have each user have
a "shadow user" whose objects he can only read and that nobody else
can see at all. he would be able to freely move objects between
his real user and his shadow one.

- Jecel