[pypy-dev] Sandbox 2

Armin Rigo armin.rigo at gmail.com
Tue Aug 13 05:37:33 EDT 2019


Hi all,

I've got an early but probably usable PyPy and PyPy3 with sandboxing.
Like the old sandboxing, these new versions are made out of a special
version of PyPy (or PyPy3, which is new), running in a mode where no
direct I/O should be possible; and a separate controller process.

The communication between these two processes has been rewritten.
Now, it actually looks similar to the communication between a process
and a OS kernel.  For example, when a regular process wants to write
data to a file, it calls the OS function "write(int fd, char *buf,
size_t count)" (actually it calls the standard C library, which is
itself a relatively thin wrapper around the OS, but we'll ignore
that).  Then the OS proceeds to read directly the part of the memory
owned by the process, from addresses "buf" to "buf + count".

In the sandboxed version of PyPy, this is replaced by the sandboxed
process saying to the controller process "I'm trying to call write()
with these three arguments: two numbers and one pointer".  Assuming
that the controller supports "write()", it contains logic that will
then ask the sandboxed process for the content of some of its memory,
from "buf" to "buf + count".

In other system calls like "read(fd, buf, count)", the controller
would write (instead of reading) data into the sandboxed process' raw
memory, between "buf" and "buf + count".

This approach means that a single sandboxed PyPy (or PyPy3) is needed,
and it supports out of the box all "system calls".  It's up to the
controller process to either support them or not, and when it does, to
do things like (if necessary) reading and writing raw memory from/to
the sandboxed subprocess.  It puts more responsibility into the hands
of the controller process, but is also far more flexible.  It is the
same security approach as for the OS, basically: the sandboxed process
can do whatever it wants but all its I/O are tightly controlled.


Sources:

* The sandboxed PyPy including the necessary RPython changes is in
PyPy's standard repo, branch "sandbox-2".  Translate with
``rpython/bin/rpython -O2 --sandbox``.

* The PyPy3 version is in the branch "py3.6-sandbox-2".  Same command
to translate.

* The controller process, or at least one possible version of it, has
been split into its own repo: http://bitbucket.org/pypy/sandboxlib .
This is CPython-or-PyPy-2-or-3 source code.  You need to run
``setup.py build_ext -f -i``.  To run the tests (with pytest), make a
symlink from ``test/pypy-c-sandbox`` to the sandboxed version built
above.  Try also ``interact.py``.

Right now there is no way to limit the amount of RAM of CPU time
consumed by the sandboxed process, but I think it should be done with
standard platform tools (e.g. ``ulimit``).


Please try it out and give me any feedback !


A bientôt,

Armin.


More information about the pypy-dev mailing list