7

I have created the a chroot jail in combination with unionfs-fuse so that I don't need to install another system inside it.

However, the resulting system's /dev entries are not readable.This is causing problems with programs needing access to /dev/random, /dev/null and /dev/urandom.

I tried to solve the issue myself by making a directory consisting of persistent files and making equivalents of the aforementioned files using mknod as described here, and then creating an unionfs:

# unionfs-fuse -o cow /chroot/files=RW:/chroot/persistent/:/ /chroot/chroot/

And then,

# chroot chroot/

But, when I try to:

# head -c 10 /dev/random | hexdump -C

I get the error:

head: cannot open `/dev/random' for reading: Permission denied

How should I work around this problem?

(I do not need access to other files in /dev like /dev/sd* or /dev/mem.)

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • `unionfs` is just one big conglomeration of ugly hacks stacked one upon the other. skip it - use shared mount trees instead. your problem is probably related to the fuse aspect though - which is probably also a word that should send up a few alarms in your head. – mikeserv Dec 15 '14 at 02:21
  • By the way, take care with `/` in your union filesystem: that creates an infinite path `/chroot/chroot/chroot/chroot/…`. Make sure that `locate` and other recursive jobs won't traverse it ad infinitum. – Gilles 'SO- stop being evil' Dec 16 '14 at 23:31
  • @Gilles - you need to `mount --make-unbindable /chroot; mount --bind / /chroot` to handle that w/ a vanilla-kernel - dunno how to address it *(or if it can be addressed)* with `unionfs`. – mikeserv Dec 17 '14 at 00:27

1 Answers1

2

The explanation lies in the mount.fuse man page:

Filesystems are mounted with nodev,nosuid by default, which can only be overridden by a privileged user

With the nodev option, the kernel bans all access to devices in the mounted filesystem. With the nosuid option, the kernel ignores setuid and setgid attributes. Both options are necessary for security when a filesystem is mounted by a non-root user: otherwise the mounting user could create a setuid root shell or devices letting him access all disks bypassing the filesystem.

You'll also want the allow_other option if non-root users are to access that filesystem.

unionfs-fuse -o cow,dev,suid,allow_other /chroot/files=RW:/chroot/persistent/:/ /chroot/chroot/

If you want to restrict which devices are visible in the chroot, then a union mount isn't the way to do that. Instead, leave dev off and mount a separate filesystem containing your desired minimal /dev. You can make that a tmpfs:

unionfs-fuse -o cow,suid,allow_other /chroot/files=RW:/chroot/persistent/:/ /chroot/chroot/
mount -t tmpfs -o mode=755 chroot-dev /chroot/chroot/dev
cp -a /dev/null /dev/zero /dev/urandom /chroot/chroot/dev
mkdir /chroot/chroot/dev/pts
mount --bind /dev/pts /chroot/chroot/dev/pts

Instead of a tmpfs, you could bind-mount a directory containing your devices ready to go. You'll need to bind-mount /dev/pts to get pseudoterminals in the chroot.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • Is there a way to allow devices only from a specific location (which would be my own versions of `/dev/{null,random,urandom}`present in `/chroot/persistent`, as discussed above)? Security is an important consideration as this is a chroot jail. –  Dec 16 '14 at 02:38
  • @user2064000 I don't think you can get that degree of control. I think the best solution would be to mount a static `/dev` on top of the union filesystem, either by bind-mounting a directory or by creating a tiny tmpfs in your mount script. – Gilles 'SO- stop being evil' Dec 16 '14 at 02:44
  • @user2064000 (see edit) Also you'll need `/dev/pts` in the chroot. – Gilles 'SO- stop being evil' Dec 16 '14 at 02:51