6

I would assume the following would work:

mkdir /tmp/chrootTest # Create chroot folder.
mkdir /tmp/chrootTest/bin # Create `/bin` in the chroot folder.
sudo mount -B /bin /tmp/chrootTest/bin/ # Bind-mount the real system's `/bin` to the chroot's `/bin`.
sudo chroot /tmp/chrootTest/ /bin/bash # Execute (open) `/bin/bash` in the chroot.

However the last command yields:

chroot: failed to run command ‘/bin/bash’: No such file or directory

I also tried copying /bin to /tmp/chrootTest/bin and giving it full permissions. However, this doesn't work either.

I would not be entirely surprised to see an error message informing me that /bin/bash can't work in its very rudimentary chroot as other files can't be found. However, the error message printed is surprising as the file clearly exists.

Why does this happen? What is necessary to successfully open a bash in a chroot?

  • 1
    Is /bin/bash a static binary, or does it have shared library dependencies (not available in chroot)? See with ldd /bin/bash. – Kusalananda Jan 18 '17 at 10:37
  • 4
    bind mounting essential system directories insides a chroot environment defeats the security purposes of doing chroot. – Rui F Ribeiro Jan 18 '17 at 11:05
  • 1
    Depending on version, distro, configuration and moon phases of Jupiter, chroot uses varying entry points to the VFS. The correct solution has always been to first cd / and then sudo chroot /tmp/chrootTest bin/bash. Notice the relative lookup of bash. Also notice that dependencies of bash still have to be accessible from inside the chroot environment. – Bananguin Jan 18 '17 at 11:40
  • 1
    @UTF-8 Found it. See my answer. – Kusalananda Jan 18 '17 at 20:06
  • 1
    @RuiFRibeiro chroot isn't good for added security, there are methods to break out of a chroot. It is useful for creating a sandbox for applications though, so you can be more sure what files/libraries/binaries it uses. – Centimane Jan 18 '17 at 20:29
13

If /bin/bash is a binary with shared library dependencies, these dependencies needs to be able to be resolved within the chroot.

On my system:

$ ldd $( command -v bash )
/usr/local/bin/bash:
        Start            End              Type Open Ref GrpRef Name
        0000115f08700000 0000115f08a0c000 exe  1    0   0      /usr/local/bin/bash
        00001161f6a2e000 00001161f6c88000 rlib 0    1   0      /usr/lib/libtermcap.so.14.0
        00001161bc41e000 00001161bc629000 rlib 0    1   0      /usr/local/lib/libintl.so.6.0
        000011614b1de000 000011614b4dd000 rlib 0    2   0      /usr/local/lib/libiconv.so.6.0
        00001161bd091000 00001161bd35b000 rlib 0    1   0      /usr/lib/libc.so.89.2
        000011612ef00000 000011612ef00000 rtld 0    1   0      /usr/libexec/ld.so

In contrast:

$ ldd $( command -v sh )
/bin/sh:
        Start            End              Type Open Ref GrpRef Name
        000007ca3c446000 000007ca3c6c6000 dlib 1    0   0      /bin/sh

I'm on OpenBSD. The format of the output of ldd will be different on a Linux system, but the same essential information (what libraries are shared, and where they are) ought to be displayed on Linux as well.

When I try with a very simplistic chroot that only contains /bin/sh and /bin/bash (doas is OpenBSD's "sudo replacement"):

$ doas chroot -u kk t /bin/sh
/bin/sh: No controlling tty (open /dev/tty: No such file or directory)
/bin/sh: warning: won't have full job control
$ /bin/bash
Abort trap

Notice that I do get a shell (/bin/sh), but that /bin/bash fails. The error is different from yours but it has, I assume, the same cause. Executing /bin/bash directly with the chroot command just gives a one-word "Abort" message, again, presumably due to the same issue with libraries.

Conclusion: The chroot needs to contain at least a minimal installation of a system, including device files and libraries that are needed to run the executables within it.

Explanation of the "No such file or directory" error on Linux:

I was a bit confused as to why the error was "No such file or directory" on Linux, so I ran a test through strace.

The execve() call that ought to have executed the shell returns ENOENT:

execve("/bin/bash", ["/bin/bash"], [/* 13 vars */]) = -1 ENOENT (No such file or directory)

... so I thought it was something wrong with finding /bin/bash. However, upon reading the execve(2) manual, I saw:

ENOENT The file filename or a script or ELF interpreter does not exist, or a shared library needed for file or interpreter cannot be found.

So there you go.

4

Make sure your install system and the Medium you use for chroot have the same arch.

Is The partition you mount to /mnt your / partition from install System?

I chroot this way.

For ext* filesystem.

sudo mount /dev/sdxY /mnt

For separate /boot bios mode partition

sudo mount /dev/sdzY /mnt/boot

For efi mode

sudo mount /dev/sdwY /mnt/boot/efi

Mount vituelle Filesystems

for dir in /dev /dev/pts /proc /sys /run; do sudo mount --bind $dir /mnt/$dir; done

For Network acess

cp -a /etc/resolv.conf /mnt/etc/resolve.conf

then

sudo chroot /mnt /bin/bash

But I only use it with Debian and Ubuntu.

1

Just modify your example code to the following: (worked for me)

mkdir /tmp/chrootTest
mkdir /tmp/chrootTest/bin
mkdir /tmp/chrootTest/lib
mkdir /tmp/chrootTest/lib64
sudo mount -B /bin /tmp/chrootTest/bin/
sudo mount -B /lib /tmp/chrootTest/lib/
sudo mount -B /lib64 /tmp/chrootTest/lib64/
sudo chroot /tmp/chrootTest/ /bin/bash

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.