Plash: frequently asked questions
Intercepting library calls
Q: If Plash relies on replacing libc, doesn't that mean that processes can get around the access restrictions by making system calls directly?
No. Plash takes away a process's authority by putting it in a chroot() jail and running it under a freshly-allocated user ID (see ChrootSetuidJail). This stops all of the filename-related system calls from doing anything much.
The modified glibc (PlashGlibc) is not used for taking away authority. It is only used for giving authority back via a different channel. glibc will communicate with a server process via a socket; this is how the filename-related Unix calls such as open() are implemented. The server can send the process file descriptors via the socket.
If a sandboxed program bypasses glibc, it will only be able to see the contents of the chroot jail. If you link a sandboxed program with the regular glibc, it probably won't work.
LD_PRELOAD
Q: Why don't you intercept libc calls using an LD_PRELOADed library rather than using a replacement libc.so?
Plash needs to be able to intercept all calls to functions such as open(). Using an LD_PRELOADed library can only replace open() as seen from outside of libc.so. It is not able to replace libc.so's internal uses of open(). These include:
- fopen() calls open()
- calls to open() to read configuration files such as /etc/hosts, /etc/hosts, /etc/resolv.conf
- calls to open() to read locale data
Other tools, such as fakeroot, fakechroot and cowdancer, use LD_PRELOADed libraries which replace fopen() as well as open(), but they are not able to handle the other cases.
It to be possible to intercept libc.so's internal calls by defining __open and __libc_open in an LD_PRELOADed library. This is no longer possible with newer versions of glibc, which resolve these symbols at static linking time. This was changed for efficiency, so that there are fewer relocations to do at dynamic link time, and so that the calls don't have to go through a jump table. There are also some cases in libc.so where the "open" syscall is inlined, such as when using open_not_cancel (a macro).
More importantly, Plash needs to replace the dynamic linker (ld-linux.so.2) so that it doesn't use the "open" syscall, and this cannot be done using LD_PRELOAD.
