bubblejail icon indicating copy to clipboard operation
bubblejail copied to clipboard

Chromium and derivatives: The SUID sandbox helper binary was found, but is not configured correctly

Open gelatinbomb opened this issue 5 months ago • 27 comments

Output of bubblejail --version

0.9.5

Your distro name and version

Kubuntu 25.04

Description

I'm getting this error when I try to run brave browser inside a sandbox.

Sandboxed PID: 25043
Bubblewrap started. PID: <Process 25042>
Started unix server
[8:8:0812/041511.756497:FATAL:sandbox/linux/suid/client/setuid_sandbox_host.cc:169] The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I'm aborting now. You need to make sure that /opt/brave.com/brave/chrome-sandbox is owned by root and has mode 4755.

This is only happening on my main pc with Kubuntu 25.04, on my laptop with Debian 13 there is no issue and Brave works well.

Any ideas of what could cause this? I saw some answers over the internet but I don't want to do anything that could damage the security of my system.

gelatinbomb avatar Aug 12 '25 10:08 gelatinbomb

Hello @gelatinbomb

It probably has something to do with the fact that Chromium sandbox has its own SUID binary. Bubblewrap uses no-new-priveledges flag to disable any SUID binaries.

From my testing it seems like Chromium should be able to detect if SUID is blocked and run unprivileged but this highly dependent on the version or config.

Maybe /.flatpak-info file can help you: #173 It seems to be the way sandboxing is indicated nowadays.

igo95862 avatar Aug 12 '25 10:08 igo95862

Modern chromium uses unprivileged userns and falls back to SUID helper if unprivileged userns isn't available.

rusty-snake avatar Aug 12 '25 11:08 rusty-snake

Hello @gelatinbomb

It probably has something to do with the fact that Chromium sandbox has its own SUID binary. Bubblewrap uses no-new-priveledges flag to disable any SUID binaries.

From my testing it seems like Chromium should be able to detect if SUID is blocked and run unprivileged but this highly dependent on the version or config.

Maybe /.flatpak-info file can help you: #173 It seems to be the way sandboxing is indicated nowadays.

If I try the --no-sandbox argument brave will launch but I don't really know if leaving the browser unsandboxed is a good idea.

gelatinbomb avatar Aug 13 '25 01:08 gelatinbomb

Hello @gelatinbomb

It probably has something to do with the fact that Chromium sandbox has its own SUID binary. Bubblewrap uses no-new-priveledges flag to disable any SUID binaries.

From my testing it seems like Chromium should be able to detect if SUID is blocked and run unprivileged but this highly dependent on the version or config.

Maybe /.flatpak-info file can help you: #173 It seems to be the way sandboxing is indicated nowadays.

Where is the ./flatpak-info file located? What should I do with it?

gelatinbomb avatar Aug 13 '25 01:08 gelatinbomb

Hello @gelatinbomb It probably has something to do with the fact that Chromium sandbox has its own SUID binary. Bubblewrap uses no-new-priveledges flag to disable any SUID binaries. From my testing it seems like Chromium should be able to detect if SUID is blocked and run unprivileged but this highly dependent on the version or config. Maybe /.flatpak-info file can help you: #173 It seems to be the way sandboxing is indicated nowadays.

If I try the --no-sandbox argument brave will launch but I don't really know if leaving the browser unsandboxed is a good idea.

Instead of --no-sandbox can you try --disable-setuid-sandbox?

https://github.com/woweijingjing/chromium-1/blob/master/docs/linux_sandboxing.md#User-namespaces-sandbox

This should mean the namespaces sandbox will be used. Check the chrome://sandbox for the sandboxing status.

For me running using namespaces sandbox the status will be:

Sandbox Status
Layer 1 Sandbox	Namespace
PID namespaces	Yes
Network namespaces	Yes
Seccomp-BPF sandbox	Yes
Seccomp-BPF sandbox supports TSYNC	Yes
Ptrace Protection with Yama LSM (Broker)	Yes
Ptrace Protection with Yama LSM (Non-broker)	No
You are adequately sandboxed.

If the SUID sandbox is used the layer 1 sandbox line would be:

Layer 1 Sandbox	SUID

This is only happening on my main pc with Kubuntu 25.04, on my laptop with Debian 13 there is no issue and Brave works well.

I might know why it is only Kubuntu causing it. At some version Ubuntu started restricting unpriviledged user namespaces using AppArmor. You can disable the block using the sysctl: https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces

sudo sysctl -w kernel.apparmor_restrict_unprivileged_unconfined=0
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0

I believe you can configure AppArmor to allow for specific applications to use namespaces but this is not something I am familiar with.

igo95862 avatar Aug 13 '25 08:08 igo95862

Hello @gelatinbomb It probably has something to do with the fact that Chromium sandbox has its own SUID binary. Bubblewrap uses no-new-priveledges flag to disable any SUID binaries. From my testing it seems like Chromium should be able to detect if SUID is blocked and run unprivileged but this highly dependent on the version or config. Maybe /.flatpak-info file can help you: #173 It seems to be the way sandboxing is indicated nowadays.

If I try the --no-sandbox argument brave will launch but I don't really know if leaving the browser unsandboxed is a good idea.

Instead of --no-sandbox can you try --disable-setuid-sandbox?

https://github.com/woweijingjing/chromium-1/blob/master/docs/linux_sandboxing.md#User-namespaces-sandbox

This should mean the namespaces sandbox will be used. Check the chrome://sandbox for the sandboxing status.

For me running using namespaces sandbox the status will be:

Sandbox Status
Layer 1 Sandbox	Namespace
PID namespaces	Yes
Network namespaces	Yes
Seccomp-BPF sandbox	Yes
Seccomp-BPF sandbox supports TSYNC	Yes
Ptrace Protection with Yama LSM (Broker)	Yes
Ptrace Protection with Yama LSM (Non-broker)	No
You are adequately sandboxed.

If the SUID sandbox is used the layer 1 sandbox line would be:

Layer 1 Sandbox	SUID

This is only happening on my main pc with Kubuntu 25.04, on my laptop with Debian 13 there is no issue and Brave works well.

I might know why it is only Kubuntu causing it. At some version Ubuntu started restricting unpriviledged user namespaces using AppArmor. You can disable the block using the sysctl: https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces

sudo sysctl -w kernel.apparmor_restrict_unprivileged_unconfined=0
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0

I believe you can configure AppArmor to allow for specific applications to use namespaces but this is not something I am familiar with.

It throws me this error:

Sandboxed PID: 27622
Bubblewrap started. PID: <Process 27621>
Started unix server
[8:8:0813/031636.461522:FATAL:content/browser/zygote_host/zygote_host_impl_linux.cc:132] No usable sandbox! If you are running on Ubuntu 23.10+ or another Linux distro that has disabled unprivileged user namespaces with AppArmor, see https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md. Otherwise see https://chromium.googlesource.com/chromium/src/+/main/docs/linux/suid_sandbox_development.md for more information on developing with the (older) SUID sandbox. If you want to live dangerously and need an immediate workaround, you can try using --no-sandbox.

I guess it's Apparmor the cause of the issue. If I understand correctly a custom Apparmor profile should work. I think it might be a good idea instead of lifting all the restrictions.

gelatinbomb avatar Aug 13 '25 09:08 gelatinbomb

I guess it's Apparmor the cause of the issue. If I understand correctly a custom Apparmor profile should work. I think it might be a good idea instead of lifting all the restrictions.

I think you can use the chromium AppArmor profile as template: https://gitlab.com/apparmor/apparmor/-/blob/a8875460edc787477e3d6b8498cbfdab98d1ec23/profiles/apparmor.d/chromium#L10

igo95862 avatar Aug 13 '25 09:08 igo95862

I guess it's Apparmor the cause of the issue. If I understand correctly a custom Apparmor profile should work. I think it might be a good idea instead of lifting all the restrictions.

I think you can use the chromium AppArmor profile as template: https://gitlab.com/apparmor/apparmor/-/blob/a8875460edc787477e3d6b8498cbfdab98d1ec23/profiles/apparmor.d/chromium#L10

What binary should I point at? I tried bubblejail in /usr/local/bin but does not seem to work.

gelatinbomb avatar Aug 13 '25 09:08 gelatinbomb

I guess it's Apparmor the cause of the issue. If I understand correctly a custom Apparmor profile should work. I think it might be a good idea instead of lifting all the restrictions.

I think you can use the chromium AppArmor profile as template: https://gitlab.com/apparmor/apparmor/-/blob/a8875460edc787477e3d6b8498cbfdab98d1ec23/profiles/apparmor.d/chromium#L10

What binary should I point at? I tried bubblejail in /usr/local/bin but does not seem to work.

Not sure. Maybe bwrap? Or does bwrap has its own profile? There is also the bubblejail helper script at /usr/lib/bubblejail/bubblejail-helper (/usr/local prefix in your case).

Maybe aa-notify can help? https://man.archlinux.org/man/aa-notify.8.html

Sorry I am not familiar with AppArmor.

igo95862 avatar Aug 13 '25 10:08 igo95862

When running Brave outside the bubblejail what does chrome://sandbox report? Maybe the Brave AppArmor profile is missing?

igo95862 avatar Aug 13 '25 11:08 igo95862

When running Brave outside the bubblejail what does chrome://sandbox report? Maybe the Brave AppArmor profile is missing?

There is a basic brave profile on /etc/apparmor.d/. It seems to run in unconfined mode.

Image

gelatinbomb avatar Aug 13 '25 11:08 gelatinbomb

I guess it's Apparmor the cause of the issue. If I understand correctly a custom Apparmor profile should work. I think it might be a good idea instead of lifting all the restrictions.

I think you can use the chromium AppArmor profile as template: https://gitlab.com/apparmor/apparmor/-/blob/a8875460edc787477e3d6b8498cbfdab98d1ec23/profiles/apparmor.d/chromium#L10

What binary should I point at? I tried bubblejail in /usr/local/bin but does not seem to work.

Not sure. Maybe bwrap? Or does bwrap has its own profile? There is also the bubblejail helper script at

Bwrap does have it's own profile. It's on enforced mode and it's quite different from the other profiles.

/usr/lib/bubblejail/bubblejail-helper (/usr/local prefix in your case).

Maybe aa-notify can help? https://man.archlinux.org/man/aa-notify.8.html

Sorry I am not familiar with AppArmor.

No problem. I'm also not someone with knowledge regarding Apparmor. I'm trying too see what I can find to make it work.

gelatinbomb avatar Aug 13 '25 11:08 gelatinbomb

Hmmm... I found this email that might be explaining what is going on: https://lists.ubuntu.com/archives/apparmor/2017-September/011080.html

From what I understand is because of "PR_SET_NO_NEW_PRIVS" the sandboxed application cannot transition between AppArmor profiles. In this case the whatever the original profile applied to bwrap does not allow the user namespaces.

igo95862 avatar Aug 13 '25 11:08 igo95862

I should add Ubuntu to the distro notes and explain how to disable user namespace block in AppArmor. (or easy way to add profile that allow them for a specific instance if you can find it)

igo95862 avatar Aug 13 '25 18:08 igo95862

Hey @igo95862 I've been running some tests to try to better understand the cause of the problem:

  1. Brave uses SUID instead of User Namespaces for the Flatpak version:
Image

In fact, if you use the "--disable-setuid-sandbox" argument, it displays the error related to restricted namespaces

Unusable sandbox! If you are running on Ubuntu 23.10+ or another Linux distro that has disabled unprivileged user namespaces with AppArmor, see https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md. Otherwise, see https://chromium.googlesource.com/chromium/src/+/main/docs/linux/suid_sandbox_development.md for more information on developing with the (older) SUID sandbox. If you want to live dangerously and need an immediate workaround, you can try using --no-sandbox.

  1. When I try to check the logs using "sudo journalctl -fx" while trying to run Brave in Bubblejail, the following message is displayed:

audit: type=1400 audit(1755241151.933:193): apparmor="DENIED" operation="capable" class="cap" profile="unpriv_bwrap" pid=6288 comm="brave" capability=21 capname="sys_admin"

This already tells us which profile is being denied. It is located in the file "/etc/apparmor.d/bwrap-userns-restrict" This file contains two profiles, bwrap and, the one we are interested in, unpriv_bwrap:

# This profile allows almost everything and only exists to allow bwrap
# to work on a system with user namespace restrictions being enforced.
# bwrap is allowed access to user namespaces and capabilities within
# the user namespace, but its children do not have capabilities,
# blocking bwrap from being able to be used to arbitrarily by-pass the
# user namespace restrictions.

# Note: the bwrap child is stacked against the bwrap profile due to
# bwraps use of no-new-privs.

abi <abi/4.0>,

include <tunables/global>

profile bwrap /usr/bin/bwrap flags=(attach_disconnected,mediate_deleted) {
  allow capability,
  # not allow all, to allow for pix stack on systems that don't support
  # rule priority.
  #
  # sadly we have to allow 'm' every where to allow children to work under
  # profile stacking atm.
  allow file rwlkm /{**,},
  allow network,
  allow unix,
  allow ptrace,
  allow signal,
  allow mqueue,
  allow io_uring,
  allow userns,
  allow mount,
  allow umount,
  allow pivot_root,
  allow dbus,

  # stacked like this due to no-new-privs restriction
  # this will stack a target profile against bwrap and unpriv_bwrap
  # Ideally
  # - there would be a transition at userns creation first. This would allow
  #   for the bwrap profile to be tighter, and looser within the user
  #   ns. bwrap will still have to fairly loose until a transition at
  #   namespacing in general (not just user ns) is available.
  # - there would be an independent second target as fallback
  #   This would allow for select target profiles to be used, and not
  #   necessarily stack the unpriv_bwrap in cases where this is desired
  #
  # the ix works here because stack will apply to ix fallback
  # Ideally we would sanitize the environment across a privilege boundry
  # (leaving bwarp into application) but flatpak etc use environment glibc
  # sanitized environment variables as part of the sandbox setup.
  allow pix /** -> &bwrap//&unpriv_bwrap,

  # the local include should not be used without understanding the userns
  # restriction.
  # Site-specific additions and overrides. See local/README for details.
  include if exists <local/bwrap-userns-restrict>
}

# The unpriv_bwrap profile is used to strip capabilities within the userns
profile unpriv_bwrap flags=(attach_disconnected,mediate_deleted) {
  # not allow all, to allow for pix stack
  allow file rwlkm /{**,},
  allow network,
  allow unix,
  allow ptrace,
  allow signal,
  allow mqueue,
  allow io_uring,
  allow userns,
  allow mount,
  allow umount,
  allow pivot_root,
  allow dbus,

  # bwrap profile does stacking against itself this will keep the target
  # profile from having elevated privileges in the container.
  # If done recursively the stack will remove any duplicate
  allow pix /** -> &unpriv_bwrap,

  audit deny capability,

  # the local include should not be used without understanding the userns
  # restriction.
  # Site-specific additions and overrides. See local/README for details.
  include if exists <local/unpriv_bwrap>
}

The same profile has an interesting comment, mentioning precisely that this profile is used to limit the capabilities of user namespaces. Could it be possible that Bubblejail calls a function that causes this profile to be denied by Apparmor?

This is quite an issue, because we clearly cannot modify the Bubblewrap profile, as I assume it was written that way to prevent security breaches. On the other hand, even Brave in Flatpak chooses to use SUID instead of User Namespaces for the sandbox.

What do you think about this situation? Do you see anything that catches your attention in the unpriv_bwrap profile?

gelatinbomb avatar Aug 15 '25 07:08 gelatinbomb

Brave uses SUID instead of User Namespaces for the Flatpak version:

It does not use the SUID sandbox. The flatpak LD_PRELOADs a library called zypack that tricks brave into thinking that it's own SUID sandbox would be used. Instead however flatpak-spawn will be used.

rusty-snake avatar Aug 15 '25 07:08 rusty-snake

Brave uses SUID instead of User Namespaces for the Flatpak version:

It does not use the SUID sandbox. The flatpak LD_PRELOADs a library called zypack that tricks brave into thinking that it's own SUID sandbox would be used. Instead however flatpak-spawn will be used.

Thanks for the clarification.

gelatinbomb avatar Aug 15 '25 07:08 gelatinbomb

Update: I tried using the sudo "sysctl -w kernel.apparmor_restrict_unprivileged_unconfined=0" and "sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0" but I still can't get Brave to work with Bubblejail. I got the SUID error and the Apparmor one with the --disable-setuid-sandbox

gelatinbomb avatar Aug 15 '25 09:08 gelatinbomb

Could it be possible that Bubblejail calls a function that causes this profile to be denied by Apparmor?

It is not bubblejail that is having issues but Chromium. Chromium tries to use its own sandbox which relies on user namespaces.

On the other hand, even Brave in Flatpak chooses to use SUID instead of User Namespaces for the sandbox.

As @rusty-snake pointed out the SUID sandbox is a lie and actually the flatpak-spawn is used. Flatpak has a priveledge of patching the applications because they are also a distribution platform.

This is quite an issue, because we clearly cannot modify the Bubblewrap profile, as I assume it was written that way to prevent security breaches.

The unprivileged user namespaces are a risk because it open a large interaction surface with kernel. However, a lot of distros (Debian, RHEL, Arch Linux...) take the risk and enable unprivileged namespaces. Bubblejail has its own namespace restrictions service but it is not enabled by default as it has to be configured for each application specifically.

What do you think about this situation?

There is not a lot that can be done:

  • Disable chromium sandboxing. (not recommended)
  • Disable user namespace block. This can probably be done on specifically for the bwrap.

igo95862 avatar Aug 15 '25 09:08 igo95862

Update: I tried using the sudo "sysctl -w kernel.apparmor_restrict_unprivileged_unconfined=0" and "sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0" but I still can't get Brave to work with Bubblejail. I got the SUID error and the Apparmor one with the --disable-setuid-sandbox

Hmm... Can you spawn a terminal inside the sandbox and try unshare --user?

igo95862 avatar Aug 15 '25 09:08 igo95862

audit: type=1400 audit(1755241151.933:193): apparmor="DENIED" operation="capable" class="cap" profile="unpriv_bwrap" pid=6288 comm="brave" capability=21 capname="sys_admin"

Hmm... Actually it might have more to do with the CAP_SYS_ADMIN rather than user namespaces.I believe when you create a new user namespace you get all capabilities within that namespace.

igo95862 avatar Aug 15 '25 09:08 igo95862

Update: I tried using the sudo "sysctl -w kernel.apparmor_restrict_unprivileged_unconfined=0" and "sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0" but I still can't get Brave to work with Bubblejail. I got the SUID error and the Apparmor one with the --disable-setuid-sandbox

Hmm... Can you spawn a terminal inside the sandbox and try unshare --user?

It gave me a clean shell without the host name just a clean "$" I did it while checking with sudo journalctl -fx and it gave me this Apparmor message:

audit: type=1400 audit(1755250140.807:199): apparmor="DENIED" operation="capable" class="cap" profile="unpriv_bwrap" pid=3303 comm="konsole" capability=19 capname="sys_ptrace"

If I do the same command outside Bubblejail and create the new namespace it properly creates a new session with the username "nobody" and this is what Apparmor throw me:

audit: type=1400 audit(1755250368.290:207): apparmor="AUDIT" operation="userns_create" class="namespace" info="Userns create - transitioning profile" profile="unconfined" pid=3488 comm="unshare" requested="userns_create" target="unprivileged_userns"

Another thing I found is that the bwrap profile is a new thing that came for Ubuntu 25.04:

Among them, a new AppArmor profile for Bubblewrap (bwrap), bwrap-userns-restrict, which is able to set up a create user namespaces and set up sandboxing, before switching to a stricter profile to limit what processes can do inside the bwrap sandbox. https://www.omgubuntu.co.uk/2025/03/ubuntu-25-04-new-features

gelatinbomb avatar Aug 15 '25 09:08 gelatinbomb

Ok. I now believe there are 2 AppArmor restrictions at work.

audit: type=1400 audit(1755250368.290:207): apparmor="AUDIT" operation="userns_create" class="namespace" info="Userns create - transitioning profile" profile="unconfined" pid=3488 comm="unshare" requested="userns_create" target="unprivileged_userns"

The apparmor="AUDIT" operation="userns_create" means the namespace restriction rule was triggered but it is set to audit mode meaning it only logged instead of blocking.

audit: type=1400 audit(1755250140.807:199): apparmor="DENIED" operation="capable" class="cap" profile="unpriv_bwrap" pid=3303 comm="konsole" capability=19 capname="sys_ptrace"

This one has something to do with capabilities. I belive audit deny capability, in unpriv_bwrap profile is what blocking it.

igo95862 avatar Aug 15 '25 09:08 igo95862

Ok. I now believe there are 2 AppArmor restrictions at work.

audit: type=1400 audit(1755250368.290:207): apparmor="AUDIT" operation="userns_create" class="namespace" info="Userns create - transitioning profile" profile="unconfined" pid=3488 comm="unshare" requested="userns_create" target="unprivileged_userns"

The apparmor="AUDIT" operation="userns_create" means the namespace restriction rule was triggered but it is set to audit mode meaning it only logged instead of blocking.

audit: type=1400 audit(1755250140.807:199): apparmor="DENIED" operation="capable" class="cap" profile="unpriv_bwrap" pid=3303 comm="konsole" capability=19 capname="sys_ptrace"

This one has something to do with capabilities. I belive audit deny capability, in unpriv_bwrap profile is what blocking it.

I commented the "audit deny capability" but Apparmor still denied it, then I commented the whole "unpriv_bwrap" profile and still managed to fail BUT when I remove the reference of "unpriv_bwrap" here

allow pix /** -> &bwrap//&unpriv_bwrap,

To this

allow pix /** -> &bwrap,

Brave launches succesfully. I checked "brave://sandbox" and it indicates everything is propely sandboxed. Work on both user namespaces and SUID.

gelatinbomb avatar Aug 15 '25 11:08 gelatinbomb

I think I will have to mark bubblejail as incompatible with AppAmor. There are too much interference between them.

igo95862 avatar Aug 15 '25 12:08 igo95862

I think I will have to mark bubblejail as incompatible with AppAmor. There are too much interference between them.

I don't think is that incompatible. After all I have been using Bubblejail in distros with Apparmor like Debian, OpenSuse, etc... for a while without any issues. At least in this case is a Ubuntu 25.04 thing since the profile was introduced here.

gelatinbomb avatar Aug 15 '25 22:08 gelatinbomb

I added Ubuntu note to the documentation: https://github.com/igo95862/bubblejail/blob/github-ci/docs/distro_notes/ubuntu.md

igo95862 avatar Aug 18 '25 01:08 igo95862