Currently, we give total access to all binaries and libraries (/bin
, /lib
, etc.) but most of them aren’t needed. I’m experimenting with a way to dynamically determine the exact binaries and libraries required by a program to mount them into the sandbox. My current approach is:
objdump
is used to determine the libraries directly required by the provided executable. ldconfig
is used to translate the basic library names (e.g. libc.so
) into their actual file path (e.g. /usr/lib/libc.so.6
). The script then recurses over each of those libraries to determine the libraries that are indirectly required. This process is repeated until all libraries have been discovered.
The issue with this however, is that an executable may call other executables that pull in their own libraries. These libraries will not be detected by this approach so the package manager then recursively checks all the dependencies required by the package which owns the executable. It repeats the above but for every library and executable in every dependency discovered (with the file list e.g. Debian -- File list of package firefox-esr/buster/amd64).
It does not use ldd
for security reasons. See the security section of the man page: ldd(1) - Linux manual page
From my initial testing this seems to be pretty thorough. It can add significant overhead to starting applications so I added a way to cache the list of required libraries.
On my system, there are 143617 files in /usr/bin
and /usr/lib
. When running Chromium with the script, there are only 1274 files available in the sandbox. That’s 0.887%.
The only issue I’ve found so far is that Krita requires too many arguments than bubblewrap can handle:
bwrap: Exceeded maximum number of arguments 9000
We may be able to resolve this and figure out a way to slim it down. Other than that, most applications seem to work fine. The script is a bit complex and messy however.
I’ve only tested this on Arch Linux with pacman but porting it to Debian/apt should be easy. Only few commands are package manager dependent.
Use it like:
findlibs /usr/bin/chromium
What do you think? Would it be worth it? Libraries aren’t particularly sensitive and they’re all read-only anyway but this could be good practice, following principle of least privilege.