Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #18724 > unrolled thread

codecs in a chroot / without fs access

Started byPhilipp Hagemeister <phihag@phihag.de>
First post2012-01-10 01:41 +0100
Last post2012-01-10 08:42 -0800
Articles 4 — 3 participants

Back to article view | Back to comp.lang.python


Contents

  codecs in a chroot / without fs access Philipp Hagemeister <phihag@phihag.de> - 2012-01-10 01:41 +0100
    Re: codecs in a chroot / without fs access Miki Tebeka <miki.tebeka@gmail.com> - 2012-01-10 08:33 -0800
    Re: codecs in a chroot / without fs access Miki Tebeka <miki.tebeka@gmail.com> - 2012-01-10 08:33 -0800
    Re: codecs in a chroot / without fs access K Richard Pixley <rich@noir.com> - 2012-01-10 08:42 -0800

#18724 — codecs in a chroot / without fs access

FromPhilipp Hagemeister <phihag@phihag.de>
Date2012-01-10 01:41 +0100
Subjectcodecs in a chroot / without fs access
Message-ID<mailman.4565.1326157245.27778.python-list@python.org>

[Multipart message — attachments visible in raw view] — view raw

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:

>>> import os
>>> os.getuid()
0
>>> os.chroot('/tmp')
>>> ''.decode('raw-unicode-escape')
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

[toc] | [next] | [standalone]


#18770

FromMiki Tebeka <miki.tebeka@gmail.com>
Date2012-01-10 08:33 -0800
Message-ID<mailman.4604.1326213236.27778.python-list@python.org>
In reply to#18724
Another option is to copy the data to the a location under the new chroot and register a new lookup functions (http://docs.python.org/library/codecs.html#codecs.register). This way you can save some memory.

[toc] | [prev] | [next] | [standalone]


#18771

FromMiki Tebeka <miki.tebeka@gmail.com>
Date2012-01-10 08:33 -0800
Message-ID<30380539.934.1326213233044.JavaMail.geo-discussion-forums@yqlf8>
In reply to#18724
Another option is to copy the data to the a location under the new chroot and register a new lookup functions (http://docs.python.org/library/codecs.html#codecs.register). This way you can save some memory.

[toc] | [prev] | [next] | [standalone]


#18773

FromK Richard Pixley <rich@noir.com>
Date2012-01-10 08:42 -0800
Message-ID<iUZOq.72517$ed2.2066@newsfe05.iad>
In reply to#18724
On 1/9/12 16:41 , Philipp Hagemeister wrote:
> 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:
>
>>>> import os
>>>> os.getuid()
> 0
>>>> os.chroot('/tmp')
>>>> ''.decode('raw-unicode-escape')
> 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

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web