Can't use subprocess.Popen() after os.chroot() - why?

Hans Mulder hansmu at xs4all.nl
Sun Sep 4 19:36:28 CEST 2011


On 4/09/11 17:25:48, Alain Ketterlin wrote:
> Erik<erik.williamson at gmail.com>  writes:
>
>> import os
>> from subprocess import Popen, PIPE
>>
>> os.chroot("/tmp/my_chroot")
>> p = Popen("/bin/date", stdin=PIPE, stdout=PIPE, stderr=PIPE)
>> stdout_val, stderr_val = p.communicate()
>> print stdout_val
>>
>> but the Popen call is dying with the following exception:
>>
>> Traceback (most recent call last):
>>    File "./test.py", line 7, in<module>
>>      p = Popen("/bin/date", stdin=PIPE, stdout=PIPE, stderr=PIPE)
>>    File "/home/erik/lib/python2.7/subprocess.py", line 679, in __init__
>>    File "/home/erik/lib/python2.7/subprocess.py", line 1224, in _execute_child
>>    File "/home/erik/lib/python2.7/pickle.py", line 1382, in loads
>>    File "/home/erik/lib/python2.7/pickle.py", line 858, in load
>>    File "/home/erik/lib/python2.7/pickle.py", line 971, in load_string
>> LookupError: unknown encoding: string-escape
>>
>> Am I missing something here? does the chroot environment need to be
>> populated with more than just the date executable in this case?
>
> Yes, because /bin/date is probably dynamically linked: you need the libs
> as well. (Try first with a statically linked executable, e.g.,
> /bin/busybox, and everything should be ok).

/bin/date also needs timezone information from either /etc/localtime
or /usr/share/zoneinfo/ (depends on whether the environment variable
TZ is set).

It may need other data files as well (e.g. for localization).

> I agree the message is strange. For some reason, subprocess is calling
> pickle.loads, which calls rep.decode("string-escape"), which probably
> needs to access some file and fails because of the chroot().

The child process tries to exec /bin/date and fails.  The child process
then pickles the resulting exception and sends it to the parent via
a pipe that the parent has created for this purpose.  The parent then
tries to unpickle the exception and fails to find the string-escape
decoder in its usual place, due to the chroot.

If you fix that, then the parent process will be able to re-raise the
exception from the child process (which may or may not confuse you).

> I woud advise to use the chroot command instead of chrooting your python
> process, if that's possible for you.

You'll find you need to copy a lot of dynamic libraries and several
data files to your chroot box, before the normal commands in /bin work.

Keep in mind that the more features you copy to the chroot jail, the
easier it becomes to escape from it.

Hope this helps,

-- HansM



More information about the Python-list mailing list