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