restricted execution
Kendall
kendall at _drakealumni_.net
Mon Apr 2 15:21:50 EDT 2001
I've looked into rexec. My experimentation hasn't led to an acceptable solution
with the rexec module. What I do now is take individual function definitions
from the user and create a class out of them, and put the class in a module of
its own. I derive the class from one I've written, which allows user code to
access common services. I embed the Python interpreter in a C++ server
application and instantiate a pool of Python objects, some for each class type
created as described above. When a computation request comes in, I find a
suitable object instance and invoke a method with PyObject_CallMethod(). I
actually call a method in the base class which handles exceptions thrown by the
user defined method. Speed is of the essence for this app, and I haven't found
as straightforward an approach with a code object and use of rexec.RExec.r_exec.
Could someone explain how I might use rexec? Here's a simplified version of the
code I now use
#---------------------------------------
# in module CalcBase
# point 1
class CalcBase:
def __init__(self):
# some init stuff
def safe_compute(self, request):
try:
return self.compute(request)
except:
# handle all exceptions
return (-1, errMsg)
def compute(self, request):
return (0, "NOOP") # "abstract method"
# end module CalcBase
#---------------------------------------
#in user defined module FooCalc
import CalcBase
# point 2
class FooCalc(CalcBase.CalcBase):
def __init__(self):
CalcBase.CalcBase.__init__(self)
def compute(self, request):
# user supplied code goes here
# user can define more functions which go here:
# end module FooCalc
My attempt at restricting access to modules like os, sys, and others is at
"point 1" I define the AllowedBuiltinList (about 65 function/object names) and
at "point 2" I put the code I mentioned in a previous post (see below).
With this approach I haven't found a way to do malicious things in user code,
but I'm rather new to Python. Also, the typical compute() method call takes 10
milliseconds, with 25% of that in the Python interpreter and glue code, and the
other 75% in the extension C++ code I'm making available to the user code
(basically a data table search API). I'd like that 25% to shrink rather than
grow. Will rexec add significat interpreter execution overhead? For reference
my benchmark "user code" is using only 2000 "ticks" of the interpreter loop in
eval_code2().
Any thoughts are appreciated!
Kendall
# remove underscores from my email address
In article <mailman.986059362.18260.python-list at python.org>, Steve Purcell
says...
>
>Kendall wrote:
>>
>> dict = {}
>> for i in AllowedBuiltinList :
>> exec "dict['" + i + "'] = " + i
>>
>> __builtins__ = dict
>> del dict
>>
>> Where the AllowedBuiltinList is missing things like __import__, open, and
>> eval.
>> If I paste this in every user defined module, have I effectively prevented all
>> access to the file system and network? I'm not letting them import sys or
>> os in their module either.
>
>
>Have you tried to use the built-in module 'rexec' for such restricted
>execution support? You might find it easier.
>
>-Steve
>
>--
>Steve Purcell, Pythangelist
>Get testing at http://pyunit.sourceforge.net/
>Any opinions expressed herein are my own and not necessarily those of Yahoo
>
More information about the Python-list
mailing list