[pypy-commit] pypy sandbox-lib: expand the interface, still only theoretical

arigo pypy.commits at gmail.com
Sun Jan 1 05:16:44 EST 2017


Author: Armin Rigo <arigo at tunes.org>
Branch: sandbox-lib
Changeset: r89283:be4412e6ecf2
Date: 2016-12-29 19:02 +0100
http://bitbucket.org/pypy/pypy/changeset/be4412e6ecf2/

Log:	expand the interface, still only theoretical

diff --git a/rpython/translator/rsandbox/src/part.h b/rpython/translator/rsandbox/src/part.h
--- a/rpython/translator/rsandbox/src/part.h
+++ b/rpython/translator/rsandbox/src/part.h
@@ -1,40 +1,46 @@
-/*** rpython/translator/rsandbox/src/part.h ***/
-
 #ifndef _RSANDBOX_H_
 #define _RSANDBOX_H_
 
 #ifndef RPY_SANDBOX_EXPORTED
-/* Common definitions when including this file from an external C project */
-
-#include <stdlib.h>
-#include <sys/utsname.h>
-
-#define RPY_SANDBOX_EXPORTED  extern
-
-typedef long Signed;
-typedef unsigned long Unsigned;
-
+#  define RPY_SANDBOX_EXPORTED  extern
 #endif
 
 
 /* ***********************************************************
 
-   WARNING: Python is not meant to be a safe language.  For example,
-   think about making a custom code object with a random byte string and
-   trying to interpret that.  A sandboxed PyPy contains extra safety
-   checks that can detect such invalid operations before they cause
-   problems.  When such a case is detected, THE WHOLE PROCESS IS
+   A direct interface for safely embedding Python inside a larger
+   application written in C (or any other language which can access C
+   libraries).
+
+   For now, there is little support for more complex cases.  Notably,
+   any call to functions like open() or any attempt to do 'import' of
+   any non-builtin module will fail.  This interface is not meant to
+   "drop in" a large amount of existing Python code.  If you are looking
+   for this and are not concerned about security, look at CFFI
+   embedding: http://cffi.readthedocs.org/en/latest/embedding.html .
+   Instead, this interface is meant to run small amounts of untrusted
+   Python code from third-party sources.  (It is possible to rebuild a
+   module system on top of this interface, by writing a custom
+   __import__ hook in Python.  Similarly, you cannot return arbitrary
+   Python objects to C code, but you can make a Python-side data
+   structure like a list or a dict, and pass integer indices to C.)
+
+   WARNING: Python is originally not meant to be a safe language.  For
+   example, think about making a custom code object with a random byte
+   string and trying to interpret that.  A sandboxed PyPy contains extra
+   safety checks that can detect such invalid operations before they
+   cause problems.  When such a case is detected, THE WHOLE PROCESS IS
    ABORTED right now.  In the future, there should be a setjmp/longjmp
    alternative to this, but the details need a bit of care (e.g. it
    would still create memory leaks).
 
-   For now, you have to accept that the process can be aborted if
-   given malicious code.  Also, running several Python sources from
-   different sources in the same process is not recommended---there is
-   only one global state: malicious code can easily mangle the state
-   of the Python interpreter, influencing subsequent runs.  Unless you
-   are fine with both issues, you MUST run Python from subprocesses,
-   not from your main program.
+   For now, you have to accept that the process can be aborted if given
+   malicious code.  Also, running several Python codes from different
+   untrusted sources in the same process is not recommended---there is
+   only one global state: malicious code can easily mangle the state of
+   the PyPy interpreter, influencing subsequent runs.  Unless you are
+   fine with both issues, you MUST run Python from subprocesses, not
+   from your main program.
 
    Multi-threading issues: DO NOT USE FROM SEVERAL THREADS AT THE SAME
    TIME!  You need a lock.  If you use subprocesses, they will likely
@@ -150,6 +156,14 @@
 */
 RPY_SANDBOX_EXPORTED void rsandbox_result_bytes(char *buf, size_t bufsize);
 
+/* If the called function returns a tuple of values, then the above
+   'result' functions work on individual items in the tuple, initially
+   the 0th one.  This function changes the current item to
+   'current_item' if that is within bounds.  Returns the total length of
+   the tuple, or -1 if not a tuple.
+*/
+RPY_SANDBOX_EXPORTED int rsandbox_result_tuple_item(int current_item);
+
 /* When an exception occurred in rsandbox_open() or rsandbox_call(),
    return more information as a 'char *' string.  Same rules as
    rsandbox_result_bytes().  (Careful, you MUST NOT assume that the
@@ -163,14 +177,38 @@
 RPY_SANDBOX_EXPORTED void rsandbox_last_exception(char *buf, size_t bufsize,
                                                   int traceback_limit);
 
+/* Installs a callback inside the module 'mod' under the name 'fnname'.
+   The Python code then sees a function 'fnname()' which invokes back
+   the C function given as the 'callback' parameter.  The 'callback' is
+   called with 'data' as sole argument (use NULL if you don't need
+   this).
+
+   When the Python 'fnname()' is called, the 'callback' is executed.  At
+   this point it can read the tuple of provided arguments using
+   rsandbox_result_...() and rsandbox_result_tuple_item().  Before
+   returning, it can use rsandbox_push_...() to push a number of
+   answers.  If more than one answer is pushed, the Python-side will get
+   them inside a tuple.  The callback cannot raise a Python-level
+   exception; if you need this, write a Python wrapper around the
+   callback, and have the callback return an error code.  (Or, of course,
+   just write the error message to stderr and call abort(), like many
+   other operations do.)
+
+   As usual, be ready to handle any broken argument combination in
+   rsandbox_result_...().
+
+   It is ok to use rsandbox_call() recursively from a callback.  Likely,
+   if you do, malicious code could in theory cause infinite recursion,
+   but any infinite recursion including this one should be caught by the
+   general detection logic and cause a Python-level
+   RuntimeError/RecursionError exception.
+*/
+RPY_SANDBOX_EXPORTED void rsandbox_install_callback(rsandbox_module_t *mod,
+                                                    const char *fnname,
+                                                    void (*callback)(void *),
+                                                    void *data);
+
 
 /************************************************************/
 
-
-/* The list of 'rsandbox_fnptr_*' function pointers is automatically
-   generated.  Most of these function pointers are initialized to
-   point to a function that aborts the sandboxed execution.  The
-   sandboxed program cannot, by default, use any of them.  A few
-   exceptions are provided, where the default implementation returns a
-   safe default (for example rsandbox_fnptr_getenv()).
-*/
+#endif


More information about the pypy-commit mailing list