There seems to be a problem in certain linux distributions where user namespace is disabled. (eg: debian, archlinux)
This affects sandboxing in google chrome/chromium as well as applications built on electron (eg: discord, slack, brave, atom, keybase, github desktop)
To check if you are affected, go to
chrome://sandbox, if you see
Namespace Sandbox: No you are affected.
Google Chrome (& Chromium) on linux uses various technologies for different layers of sandboxing & despite people noting possible security problems with the use of SUID sandboxing google still continue to support it (for legacy/compatibility).
Chrome supports user namespaces for Layer-1 sandboxing as well as using seccomp-bpf for Layer-2.
Looking at the chromium mailing list you can see some points against the use of setuid (from 2013).
The setuid sandbox has to go:
- For each "chroot me" event, the current mechanism requires having previously started a setuid helper. This is not compatible with a more generic and universal Zygote. It is in conflict with the flexibility we want for Mojo.
- chroot helpers are tied to new PID and network namespaces. Again, this conflicts with flexibility as network namespaces use a lot of kernel memory.
- Shipping a setuid binary on Linux and on Chrome OS is bad for security.
- Having to update a setuid executable on our bots when we want to make changes is problematic
The Problem #
Although user namespace has been supported by the linux kernel since 3.8 it is not enabled by default on some linux distributions. (So far I have only noticed this on Archlinux & Debian)
If you check your lxc config you may think everything is fine.
$ lxc-checkconfig --- Namespaces --- Namespaces: enabled Utsname namespace: enabled Ipc namespace: enabled Pid namespace: enabled User namespace: enabled Network namespace: enabled
If you check your kernel config you will probably find user namespace is enabled
zcat /proc/config.gz | grep CONFIG_USER_NS CONFIG_USER_NS=y
But if you check chrome / chromium
chrome://sandbox will show the namespace sandbox is not being used.
This is because
unprivileged_userns_clone variable is disabled.
sysctl kernel.unprivileged_userns_clone kernel.unprivileged_userns_clone = 0
You will need to enable this in order to use the namespace sandbox.
The Fix #
To fix this you need to enable the
unprivileged_userns_clone variable in the kernel.
sudo sysctl -w kernel.unprivileged_userns_clone=1
Now when you run chromium,
chrome://sandbox should show the namespace sandbox is enabled.
To make this change permanent add the user namespace setting to
sudo sh -c "echo 'kernel.unprivileged_userns_clone=1' > /etc/sysctl.d/00-userns.conf"
Forcing Namespace Sandbox #
I added a check in my chrome script on github to check if user namespace is enabled before executng chromium. (if it is not enabled you get an error message with information on google chromium sandboxing on linux)
# Check if user namespaces is enabled (for sandbox) # Note: this is to enforce user namespaces for Layer-1 sandbox if [[ ! (-r /proc/sys/kernel/unprivileged_userns_clone && $(< /proc/sys/kernel/unprivileged_userns_clone) == 1 && -n $(zcat /proc/config.gz | grep CONFIG_USER_NS=y) ) ]]; then echo "User namespaces are not detected as enabled on your system, this is required for Layer-1 sandbox" echo "No usable sandbox! Update your kernel or see https://github.com/chromium/chromium/blob/master/docs/linux_sandboxing.md for more information." exit 1 fi