Search code examples
socketstcpsandboxpypy

How to create socket in pypy sandbox


I am trying to use pypy sandbox to run some untrusted python code from users on my http server. The python code is frameworked by me and the framework needs to talk with a process on another server. So I am trying to create a socket to do the communication. I did find a post few years ago how to create a tcp connection at: Using the socket module in sandboxed Pypy

It looks very promising, but seems not work for me:

    $./sandbox/pypy_interact.py goal/pypy-c
    >>import os
    >>fd = os.open("abc", os.O_RDWR|os.O_CREAT)
    Traceback (most recent call last):
       File "<stdin>", line 1, in <module>
       OSError: [Errno 2] No such file or directory: 'abc'
    >>fd = os.open("tcp://10.0.0.5:5000", os.O_RDWR|os.O_CREAT)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      OSError: [Errno 2] No such file or directory: 'tcp://10.0.0.5:5000'

I also tried to build the sandbox with _socket module by: pypy ../../rpython/bin/rpython -O2 --sandbox targetpypystandalone --withmod-_socket

However, the build hit the an assert isinstance(ll_ptrtype, Ptr) and then failed.

Is there any solution to make tcp connection in the pypy sandbox 2.3.1, or I did something wrong?


Solution

  • The line os.open("tcp://10.0.0.5:5000"), when run inside the sandbox, merely asks the outer process for that file. This outer process is pypy_interact.py. So when the sandboxed process says os.open(anything), then the logic in pypy_interact.py receives this open request, and can handle it however it wants.

    You're free to make any change to this outer controlling process --- for example, to parse strings that starts with "tcp://" and handle them by opening a real socket. (Be careful when parsing the string, to not accept random host names or crash upon malformed strings.) This is not something that is available out of the box.

    Note that if you implement this feature, please contribute it back to PyPy. As the link to the other question shows, it's something that isn't too hard to do and has been done before (more than once), but no-one has contributed it back to PyPy.