On Mon, 2003-03-03 at 08:42, Ben Laurie wrote:
I think the fundamental problem for rexec is that you don't have a security kernel. The code for security gets scatter throughout the interpreter. It's hard to have much assurance in the security when its tangled up with everything else in the language.
You can use a proxy for an object to deal with goal #1 above -- enforce an interface for an object. I think about this much like a hardware capability architecture. The protected objects live in the capability segment and regular code can't access them directly. The only access is via a proxy object that is bound to the capability.
Regardless of proxy vs. rexec, I'd be interested to hear what you think about a sound way to engineer a secure Python.
I'm told that proxies actually rely on rexec, too. So, I guess whichever approach you take, you need rexec.
The problem is that although you can think about proxies as being like a segmented architecture, you have to enforce that segmentation. And that means doing so throughout the interpreter, doesn't it? I suppose it might be possible to abstract things in some way to make that less widespread, but probably not without having an adverse impact on speed.
The boundary between the interpreter and the proxy is the generic type object API. The Python code does not know anything about the representation of a proxy object, except that it is a PyObject *. As a result, the only way to invoke operations on its is to go through the various APIs in the type object's table of function pointers. There are surely limits to how far the separation can go. I expect you can't inherit from a proxy for a class, such that the base class is in a different protection domain than the subclass. But I think there are fewer ad hoc restrictions than there are in rexec. I think this provides a pretty clean separation of concerns, even if the proxy object were a standard part of Python. The only code that should manipulate the proxy representation is its implementation. The only other step would be to convince yourself that Python does not inspect arbitrary parts of a concrete PyObject * in an unsafe way. Jeremy