[Python-Dev] Re: Capabilities - published interfaces (original) (raw)

Luke Kenneth Casson Leighton lkcl at lkcl.net
Sat Dec 20 07:19:42 EST 2003


capabilities: the means to make code disappear.

thing is that there is a lot of code.

some of the boundaries have already been highlighted where the "Capabilities" have not sufficiently been restricted.

object.class is a good example.

Access to class

the obvious solution to fix that particular problem is to turn the access to class around.

the problem is that by creating objects, as many __class__es are created as there are objects. considering restricting access to all of those __class__es is totally daunting and impractical.

... but look at it closely: they're all the same function name, so it's not necessarily the individual __class__es that could be restricted but the method by which class is accessed.

if you "feed" access to class via a single function, you have a bottleneck again which can be replaced.

so, the proposal is simple: create an builtin function called get_class through which access to class is made.

it takes, as a first argument, the class itself.

obj.class is redirected to it (builtin.get_class(obj)) to maintain code compatibility.

then it becomes possible to over-ride the get_class function and to "vet" it in a restricted execution mode.

again, it's worth reiterating here that if it wasn't for the fact that python is run "initiated" in "unrestricted" mode and "jumps down" to "restricted" execution, this wouldn't be a problem.

the reason for that is because if you ran python initiated in a file-restricted mode from startup, no unrestricted file objects with write permission would be created, such that there would be zero risk of anyone getting an unrestricted file object, through which the file.class.new(file.class, ....) method could be called.

anyway. if that is not practical (for whatever reason), then you leave it alone, and consider the function new instead, which i believe is the real reason why access to class is considered bad.

again, turning it round by creating a function builtin.new() is a way forward because that function can be restricted.

Access to builtins and globals from the stack.

i don't know if this is the case, but it's worth mentioning, as background, to avoid potential confusion.

there's the concept of globals, locals and there's builtins in the python language.

in the implementation of the python language, there are c-variables which may be global, may be local: possible conceptual confusion between the implementation and the language need to be avoided!

my question is:

_is_ it possible to make a function call in python
such that that function's "view" of what the globals,
locals and __builtins__ are are COMPLETELY different
from what the CALLER of that function's view of globals,
locals and __builtins__?

in other words, is globals() global in the python implementation, or is globals() copied on the function-call stack frame in the python implementation? [or other]

what i am getting at is that it needs to be possible, if capabilities are to work, to be able to make a transition in the python language from a full-featured mode in one function call into a totally restricted mode in another function call, and to be able to come back again.

without the entry into the restricted mode having any damaging consequences on the full-featured mode.

i note, for example, in the rexec.py code, that only self.locals is modified in the runcode() example RestrictedConsole class.

why is only self.locals['builtins'] restricted, not self.globals?

am i missing something here?

surely the globals should be modified too?

what happens if self.globals is reassigned?

Access to interfaces

one of the things that is strangely lacking in python is the ability to restrict access to python objects, a la public, protected and private from c++.

perl users find this to be utterly incomprehensible and reprehensible, especially the bits where conventions are obeyed - and followed! - about putting underscores in front of function names.

from a restricted execution perspective, this is not really okay.

what i propose is that two additional per-class functions (or lists) be added (two more functions later) which can ONLY be called from init: they are called set_public_interface() and set_protected_interface().

these functions take, as arguments, a list - or simpler yet, two variables are added which can only be initialised in init: public_interface and protected_interface.

basically they consist of lists of functions that can be accessed publicly and by inheriting classes respectively.

the reason for not specifying a list of private functions is because it then becomes necessary to explicitly search through that list excluding things from external access, which is not the way "Capabilities" are done.

if the lists are None, there are no restrictions.

if the lists are empty, no functions are accessible - which is different.

what i also propose is that it be possible to make a copy of a class and then remove items from these two lists.

it must not be possible to either add to or to replace the list items or the lists themselves.

there's quite a lot here.

i hope you find it useful.

l.



More information about the Python-Dev mailing list