[Python-3000] Will we have a true restricted exec environment for python-3000?

Vineet Jain vinj at alumni.rice.edu
Sun Apr 9 15:32:24 CEST 2006


> around to it before 2.5 goes final.  Without thinking much, I expect
> this would be a special build (ie, require a compile time flag to
> activate).
>   
python_light should be built just like any other module that you can 
import into a CPython application.
> your needs are. If you just want to say "exit this script if it ran
> more than N seconds" you can just modify the eval loop (*).  But I
This is all that is needed. Any more logic for time management should be 
added to the application. I should be able to say:

import python_light
pl = python_light.get_new_interpreter()
pl.load_module('max_module_memory': '5M', 'time_limit':'2S', 
'allow_imports':False, 'allow_introspection': False}, module_name)
pl.module_name.global_variable = [1,2,3]  #add variables to the user modules
pl.module_name.global_function = some_custom_function  #add functions to 
the user module
return_value = pl.run_function({'time_limit':'10S', 
'allow_imports':False, 'allow_introspection': False}, module_name, func, 
params, *args, **kwargs)
pl.remove(module_name)

By default:
    1. Python_light will not allow_introspection will not allow the use 
of getattr/setattr/delattr, make any identifier using double-preceding 
and double-trailing underscores.
    2. Will not allow use of eval or access to locals() or vars()
    3. Not allow any imports
    4. Restrict memory usage to a default (of say 10M)
    5. Limit time_of_execution to each call to python_light of 10S

Its important (at least in my use case) that the python_light 
application runs in the same process and you are able to initialize the 
user_module with global variables (which are of standard python types). 
Most of my users will not know python, let alone be programmers, so the 
scripts and functions they write will be fairly simple. It is up to the 
application builder to ensure that any data type (not of a standard 
python type: number, string, boolean, and list or tuple of standard 
python types) function, or  module passed to python_light is secure.

Couple of questions/notes:
1. It is assumed that python_light will pass on exceptions in user_scripts
2. Given all of the above restrictions, will python_light be 100% 
secure? If not, are there other restrictions we can add to make it 100% 
secure?
3. You should be able to instantiate multiple python_light interpreters 
in one CPython application

Nice to Have:
1. Make load_time of python_light faster than that of CPython.
2. Reduce default memory_required by each instance of a python_light 
interpreter
> difficult in total.  No one has volunteered to help lead such a task. 
> It would be great if you found a bunch of interested people and were
> able to complete all of your ideas.
>   
My needs are immediate. Nothing would make me happier, if I could do all 
the above without leaving python. I'm guessing that my users would also 
be happy with python (than say Lua). I would be willing to work with 
Nick, and whoever else that is interested, to make this a reality.

Vineet

> n
> --
> (*) here's the naive impl.  You could use cpu time instead of wall
> time if you wanted.  Making this a real patch is left as an exercise
> to the reader.
>
> Index: Python/ceval.c
> ===================================================================
> --- Python/ceval.c      (revision 43738)
> +++ Python/ceval.c      (working copy)
> @@ -16,6 +16,8 @@
>
>  #include <ctype.h>
>
> +static time_t stop_time = 0;
> +
>   #ifndef WITH_TSC
>
>  #define READ_TIMESTAMP(var)
> @@ -744,6 +746,9 @@
>         assert(stack_pointer != NULL);
>         f->f_stacktop = NULL;   /* remains NULL unless yield suspends frame */
>
> +       /* XXX: This is just here to initialize.  It should be elsewhere. */
> +       if (!stop_time)
> +               stop_time = time(NULL) + 5;
>   #ifdef LLTRACE
>         lltrace = PyDict_GetItemString(f->f_globals, "__lltrace__") != NULL;
>   #endif
> @@ -842,6 +847,11 @@
>                 }
>
>         fast_next_opcode:
> +               if (stop_time < time(NULL)) {
> +                       fprintf(stderr, "Exceeded maximum time allowed.\n");
> +                       exit(1);
> +               }
> +
>                 f->f_lasti = INSTR_OFFSET();
>
>                 /* line-by-line tracing support */
>
>
>   




More information about the Python-3000 mailing list