I followed up with my ISP. Here's the answer I got:
The os.exec call prepends the chroot directory to the absolute path,
but does NOT provide chroot for the child process. However, as long
as the environment is maintained, which contains an LD_PRELOAD, the
"chroot" will also be maintained. If LD_PRELOAD is removed or
ignored, then the chroot is ineffective.
So it appears that as long as LD_PRELOAD is set (possibly to link the
process to some other libraries than is usually the case), any
affected processes are effectively jailed. This doesn't really sound
like a traditional chroot environment, though.
Another way of saying it is that every process is responsible for
providing and maintaining the chroot through the LD_PRELOAD variable.
Those processes only maintain the chroot if that variable remains set.
Right.
The only solution that would bypass this problem altogether would be a
statically linked python. (is that possible?) It would have to be
statically linked to a custom-modified glibc to provide the virtual
chroot environment.
Some solutions depend on linking to restricted libraries, and the Wiki
page you referenced probably talks about them as well. I was thinking
that if I were to attempt to properly sandbox any current version of
CPython, I'd start off linking it to restricted libraries which
provide compatible interfaces for things like opening file handles;
then I'd put various policy controls in those libraries so that you
can have some control over what your programs do. Finally, you'd have
to stop arbitrary (extension) module loading in order to prevent
programs importing some nice modules and getting round the controls:
for example, importing socket or os to get access to file handles (or
to process creation which might get around the controls as suggested
above). Eventually, this arrives more or less at where Brett Cannon is
supposed to be right now with his sandboxed Python, perhaps by a
different route and with some different outcomes.
I notice that you've mailed me about a solution that I mentioned in
the past, but I'll respond here in order to air the ideas in public. I
looked into chroot "jails" and saw that some solutions exist for
populating directories with enough files for things like daemons or
services to be executed within the chroot environment. I also looked
at ways to break out of chroot environments, and there's a fairly well-
known trick involving open file handles which will do this effectively
for non-root users. What I then considered was the possibility of
avoiding population of a chroot filesystem by calling chroot and
setuid on a minimal "jailer" process which then loads a jailed program
after having imported a permitted set of modules.
I don't have the details with me now, but I'll probably upload the
code in the near future and post some kind of explanation of what it
does here. I'm tempted to say that the better solution involves the
restricted libraries solution mentioned above, and a nice side-effect
of that could be a more modular CPython that would benefit people
using the software in embedded environments: you'd have to insulate
the virtual machine from even the most central modules, meaning that
they could potentially be detached completely in places where memory
and storage are better used on other things.
Paul