Name

run-as-anonymous — Start process with an unused UID, in a chroot() environment

Synopsis

run-as-anonymous command args...

Description

run-as-anonymous is a small setuid-root program for starting processes such that they are isolated from the rest of the system. It chooses a UID for the process that is not being used by other processes. It sets the process's root directory using chroot().

run-as-anonymous is part of Plash. Plash uses it to give a user protection from the programs they run.

Only a small part of Plash, including run-as-anonymous, needs root access to install. If you are a system administrator, this means you can inspect this part and install it in confidence that it won't interfere with the rest of your system. You don't have to trust the rest of Plash, which is more complex -- though your users will trust the rest of Plash if they use it.

The chroot() jail

The chroot() jail directory is typically /var/lib/plash-chroot-jail. It needs to be on a writable filesystem because it contains a lock directory.

The jail directory typically contains one directory, special, which can be writable by a normal user without effectively giving that user root authority. (This is not relevant if you are installing an RPM or Debian package of Plash.)

The jail directory should not be writable by a normal user. If this were so, the user could hard link a setuid-root executable into the jail directory, and put a file lib/ld-linux.so.2 containing their own code into the jail directory. Running this executable using run-as-anonymous would run the user's code with root permission. The user would effectively have root authority.

The idea behind the special directory is that no setuid-root executable will depend on the contents of /special.

Typically, special will only contain Plash's version of glibc's dynamic linker, ld-linux.so.2. The dynamic linker is invoked as an executable. It will load a normal executable from a file outside the chroot jail, via the file descriptors that it is passed. run-as-anonymous does execve() after changing the root directory, so there needs to be an executable in the chroot jail to call execve() on.

Allocating user IDs

run-as-anonymous allocates UIDs from a numeric range that is specific as a compile time option (typically 0x100000 to 0x200000) -- see config.sh.

It creates lock files to ensure that UIDs are not re-used. The lock files are typically kept in /var/lib/plash-chroot-jail/plash-uid-locks.

The program gc-uid-locks can be run every so often to remove lock files when the corresponding UID is no longer used by any process.

The file /var/lib/plash-chroot-jail/plash-uid-locks/flock-file is locked using flock() to ensure that gc-uid-locks does not run concurrently with any instance of run-as-anonymous.

Authority granted and denied

Putting a process in a chroot() jail can deny it the ability to open most files. Giving a process a unique UID denies the ability to send signals to other processes (using kill()) or take over other processes (using ptrace()).

A process can communicate with the outside world using the file descriptors it was created with, including receiving other file descriptors (via Unix domain sockets). This is how Plash grants a process authority, after run-as-anonymous has taken away authority that could be exercised through the more usual system calls.

Note that if a process receives a directory file descriptor, it can use that to break out of its chroot() jail, using fchdir(). Plash is careful not to pass a process any directory file descriptors.

run-as-anonymous does not prevent a process from connecting to or listening on network sockets.

See also

gc-uid-locks, plash

/usr/share/doc/plash

Author

Mark Seaborn <mseaborn@onetel.com>