codecs in a chroot / without fs access

  • Thread starter Philipp Hagemeister
  • Start date
P

Philipp Hagemeister

I want to forbid my application to access the filesystem. The easiest
way seems to be chrooting and droping privileges. However, surprisingly,
python loads the codecs from the filesystem on-demand, which makes my
program crash:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>

(Interestingly, Python goes looking for the literal file "<stdin>" in
sys.path. Wonder what happens if I touch
/usr/lib/python2.7/dist-packages/<stdin>).

Is there a neat way to solve this problem, i.e. have access to all
codecs in a chroot?


If not, I'd love to have a function codecs.preload_all() that does what
my workaround does:

import codecs,glob,os.path
encs = [os.path.splitext(os.path.basename(f))[0]
for f in glob.glob('/usr/lib/python*/encodings/*.py')]
for e in encs:
try:
codecs.lookup(e)
except LookupError:
pass # __init__.py or something


enumerate /usr/lib/python.*/encodings/*.py and call codecs.lookup for
every os.path.splitext(os.path.basename(filename))[0]

Dou you see any problem with this design?


- Philipp


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)

iEYEAREKAAYFAk8LiSIACgkQ9eq1gvr7CFz0gQCgnF2n2+Wg8aArEvbWD0pxdKXL
ttcAoLczX1p7qJNGh2UPF8WXGCSwS9dM
=uuiz
-----END PGP SIGNATURE-----
 
K

K Richard Pixley

I want to forbid my application to access the filesystem. The easiest
way seems to be chrooting and droping privileges. However, surprisingly,
python loads the codecs from the filesystem on-demand, which makes my
program crash:

Traceback (most recent call last):
File "<stdin>", line 1, in<module>

(Interestingly, Python goes looking for the literal file "<stdin>" in
sys.path. Wonder what happens if I touch
/usr/lib/python2.7/dist-packages/<stdin>).

Is there a neat way to solve this problem, i.e. have access to all
codecs in a chroot?

The traditional solution is to copy the data you want to make available
into the subdirectory tree that will be used as the target of the chroot.
If not, I'd love to have a function codecs.preload_all() that does what
my workaround does:

import codecs,glob,os.path
encs = [os.path.splitext(os.path.basename(f))[0]
for f in glob.glob('/usr/lib/python*/encodings/*.py')]
for e in encs:
try:
codecs.lookup(e)
except LookupError:
pass # __init__.py or something


enumerate /usr/lib/python.*/encodings/*.py and call codecs.lookup for
every os.path.splitext(os.path.basename(filename))[0]

Dou you see any problem with this design?

Only the timing. If you're using the shell level chroot(1) program then
you're already chroot'd before this can execute. If you're using
os.chroot, then:

a) you're unix specific
b) your program must initially run as root
c) you have to drop privilege yourself rather than letting something
like chroot(1) handle it.

As alternatives, you might consider building a root file system in a
file and mounting it separately on a read-only basis. You can chroot
into that without much worry of how it will affect your regular file system.

With btrfs as root, you can create snapshots and chroot into those. You
can even mount them separately, read-only if you like, before chrooting.
The advantage of this approach is that the chroot target is built
"automatically" in the sense that it's a direct clone of your underlying
root file system, without allowing anything in the underlying root file
system to be altered. Files can be changed, but since btrfs is
copy-on-write, only the files in the snapshot will be changed.

--rich
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,150
Members
46,697
Latest member
AugustNabo

Latest Threads

Top