2

I am attempting to script the creation of a chroot jail (I know that there are tools for this, but I am in it for the experience, so please don't recommend a tool). I have a script which looks up commands that I wish to be runnable within the jail, looks up their dependencies, follows symbolic links, and then copies everything to the jail. Here is that script setup for python only.

executables="
python
"

for exe in $executables
do
        # move the executable
        echo Executable: $exe
        exe_path=`which $exe`
        echo READLINK -f $exe_path
        exe_true_path=`readlink -f $exe_path`
        exe_dir=`echo $exe_path | grep -o '/.*/'`
        mkdir -p $1$exe_dir
        cp -L $exe_true_path $1$exe_path

        # get the libs for this exe
        libs=`ldd $exe_true_path | grep -o '/[^()]*'`

        # move each lib
        for lib in $libs
        do
                echo Library: $lib
                lib_path=$lib
                lib_true_path=`readlink -f $lib_path`
                lib_dir=`echo $lib_path | grep -o '/.*/'`
                echo MKDIR $1$lib_path
                mkdir -p $1$lib_path
                echo CP $lib_true_path $1$lib_path
                cp -L $lib_true_path $1$lib_path
        done
done

It seems to work quite well...

$ tree .
.
+-- lib
¦   +-- x86_64-linux-gnu
¦       +-- libc.so.6
¦       ¦   +-- libc-2.13.so
¦       +-- libdl.so.2
¦       ¦   +-- libdl-2.13.so
¦       +-- libgcc_s.so.1
¦       ¦   +-- libgcc_s.so.1
¦       +-- libm.so.6
¦       ¦   +-- libm-2.13.so
¦       +-- libpthread.so.0
¦       ¦   +-- libpthread-2.13.so
¦       +-- libutil.so.1
¦       ¦   +-- libutil-2.13.so
¦       +-- libz.so.1
¦           +-- libz.so.1.2.7
+-- lib64
¦   +-- ld-linux-x86-64.so.2
¦       +-- ld-2.13.so
+-- usr
    +-- bin
        +-- python

However, when it comes to actually running python within this jail, I get a permissions error.

$ sudo chroot chroot12/ python --version
chroot: failed to run command `python': Permission denied

Even after I open up the permissions, I get the error.

$ chmod -R 777 chroot12/
$ sudo chroot chroot12/ python --version
chroot: failed to run command `python': Permission denied

Any ideas what might be causing this? I didn't start getting these errors until I introduced the link following, but I unfortunately don't have the older version of the script to compare with.

Thanks in advance!

strace output

$ sudo strace -f chroot chroot12 python --version
execve("/usr/sbin/chroot", ["chroot", "chroot12", "python", "--version"], [/* 14 vars */]) = 0
brk(0)                                  = 0x11f1000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f329f926000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=26406, ...}) = 0
mmap(NULL, 26406, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f329f91f000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\360\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1599536, ...}) = 0
mmap(NULL, 3713144, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f329f37e000
mprotect(0x7f329f500000, 2093056, PROT_NONE) = 0
mmap(0x7f329f6ff000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x181000) = 0x7f329f6ff000
mmap(0x7f329f704000, 18552, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f329f704000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f329f91e000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f329f91d000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f329f91c000
arch_prctl(ARCH_SET_FS, 0x7f329f91d700) = 0
mprotect(0x7f329f6ff000, 16384, PROT_READ) = 0
mprotect(0x607000, 4096, PROT_READ)     = 0
mprotect(0x7f329f928000, 4096, PROT_READ) = 0
munmap(0x7f329f91f000, 26406)           = 0
brk(0)                                  = 0x11f1000
brk(0x1212000)                          = 0x1212000
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=1534672, ...}) = 0
mmap(NULL, 1534672, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f329f7a5000
close(3)                                = 0
chroot("chroot12")                      = 0
chdir("/")                              = 0
execve("/usr/local/sbin/python", ["python", "--version"], [/* 14 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/local/bin/python", ["python", "--version"], [/* 14 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/sbin/python", ["python", "--version"], [/* 14 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/bin/python", ["python", "--version"], [/* 14 vars */]) = -1 EACCES (Permission denied)
execve("/sbin/python", ["python", "--version"], [/* 14 vars */]) = -1 ENOENT (No such file or directory)
execve("/bin/python", ["python", "--version"], [/* 14 vars */]) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/locale.alias", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "chroot: ", 8chroot: )                 = 8
write(2, "failed to run command `python'", 30failed to run command `python') = 30
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, ": Permission denied", 19: Permission denied)     = 19
write(2, "\n", 1
)                       = 1
close(1)                                = 0
close(2)                                = 0
exit_group(126)                         = ?
  • 1
    Maybe use strace to see what it's trying to access when it gets the error. – Barmar Oct 30 '14 at 18:48
  • python is not a valid shell. Try using bash then once in the changeroot, run python --version: chroot chroot12/ -s /bin/bash – eyoung100 Oct 30 '14 at 18:52
  • Have you run an ls -lAR on chroot12 and looked for "obvious" problems? (And maybe post the output?) Also, are you doing the link stuff just as a learning exercise? I think you could just cp $lib_path $1$lib_path and get the right result. – G-Man Oct 30 '14 at 19:08
  • @Barmar like so? $ sudo chroot chroot12/ strace python --version chroot: failed to run command 'strace': Permission denied @eyoung100 bash seems to be blocked too: $ sudo chroot chroot12/ chroot: failed to run command '/bin/bash': Permission denied @G-Man I am not totally familiar with those options. Let me get back to you. – Rip Leeb Oct 30 '14 at 19:10
  • Put the strace outside the jail, like so: sudo strace -f chroot chroot12 python --version – Celada Oct 30 '14 at 19:12
2

The only way I am able to reproduce the error:

execve("/usr/bin/python", ["python", "--version"], [/* 14 vars */]) = -1 EACCES (Permission denied)

...is by making the ELF dynamic loader non-executable.

This works:

$ ls -l chroot12/lib64/ld-linux-x86-64.so.2 
-rwxr-xr-x 1 root root 149280 Oct 30 16:22 chroot12/lib64/ld-linux-x86-64.so.2

This doesn't:

$ ls -l chroot12/lib64/ld-linux-x86-64.so.2 
-rw-r--r-- 1 root root 149280 Oct 30 16:22 chroot12/lib64/ld-linux-x86-64.so.2

Make sure chroot12/lib64/ld-linux-x86-64.so.2 has execute permission.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.