Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(linux): Don't setuid chrome-sandbox when not required #8368

Merged
merged 2 commits into from
Jul 22, 2024

Conversation

pimterry
Copy link
Contributor

Fix #7545 (already closed but as stale, not actually fixed)

Setuid for chrome-sandbox is not needed on the vast majority of systems where user namespaces are available, as this more secure mechanism is used for sandboxing instead. Root setuid binaries like this are a general security risk, and appear to cause specific problems in various cases today (e.g. making a deb package unusable on Ubuntu 24.04: httptoolkit/httptoolkit#602, making rpm packages fail validation on Fedora: bitwarden/clients#5153)

User namespaces were implemented in 2013 (kernel 3.8), and have been enabled by default widely for many years. Chrome themselves stopped setting this in 2016, describing it as unnecessary on all supported Linux platforms: https://issues.chromium.org/issues/40462640.

The only other case I'm aware of where setuid is required despite user namespace support is Electron <5. This electron version has been end-of-life since 2019 (more than 4 years ago) so hopefully that's not a concern, but if Electron Builder supports very old electron versions then this may be a breaking change.

This PR checks whether they're supported (i.e. /proc/self/ns/user is a symlink) and briefly tests that they work correctly (running true in a separate user namespace), and then sets the setuid bit only if that fails. This is the same test approach as used to detect sandboxing support in Nix: https://github.com/NixOS/nix/blob/40f80e1b5cf2bebb6d1d8c9efac1d982a540d555/tests/functional/common/vars-and-functions.sh#L180-L182

Copy link

changeset-bot bot commented Jul 22, 2024

🦋 Changeset detected

Latest commit: b7ed5d6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 8 packages
Name Type
app-builder-lib Patch
dmg-builder Patch
electron-builder-squirrel-windows Patch
electron-builder Patch
electron-forge-maker-appimage Patch
electron-forge-maker-nsis-web Patch
electron-forge-maker-nsis Patch
electron-forge-maker-snap Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

netlify bot commented Jul 22, 2024

Deploy Preview for car-park-attendant-cleat-11576 failed.

Name Link
🔨 Latest commit 2c890cd
🔍 Latest deploy log https://app.netlify.com/sites/car-park-attendant-cleat-11576/deploys/669e8abfc4fa1d0008e4292d

@pimterry
Copy link
Contributor Author

I've patched the various commit/changeset warnings here, but also I've just discovered the wider underlying cause of these recent issues: electron/electron#41066. All Electron apps are effectively broken on Ubuntu 24.04 right now due to related user namespacing restrictions, and it may be that while actually skipping this setuid is useful, since that would imply the test here will fail in those environments, this doesn't actually solve my problem... I'll keep digging there.

This isn't a blocker for this though, so this may still be useful to explore and/or merge here regardless, since setuid really shouldn't be required here anyway! I strongly suspect Ubuntu will revert this change from 24.04 (Mint and others have already done so) so it'll work there too soon.

@mmaietta mmaietta changed the title Don't setuid chrome-sandbox when not required fix(linux): Don't setuid chrome-sandbox when not required Jul 22, 2024
This is not necessary in many environments, so we now test for whether
this is required and then enable it only when necessary.
@mmaietta mmaietta merged commit 2acdf65 into electron-userland:master Jul 22, 2024
13 checks passed
@xmedeko
Copy link

xmedeko commented Oct 24, 2024

@pimterry The problem with apparmor in Ubuntu 24 is twofold: one with SETUID and one with execvp and space in path, see my comment #8440 (comment) and my comment in Comment 157 for bug Ubuntu aparmor 2046844

So, setting SUID always as before is workaround for apps without space in installation path.

@pimterry
Copy link
Contributor Author

@xmedeko Hmm, the test here should cover that though - on my machine, if user namespaces are disabled (sysctl -w kernel.apparmor_restrict_unprivileged_userns=1) then the check here detects that (specifically, unshare --user true fails) and so this correctly sets SUID just as it used to.

This should only disable SUID in environments where user namespaces are genuinely available. Is that not what you're seeing?

@xmedeko
Copy link

xmedeko commented Oct 24, 2024

@pimterry Do you mean set to 0 to disable it: sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 ? Note: this change is only until next reboot, while file SUID is permanent. (To switch off kernel.apparmor_restrict_unprivileged_userns permanently, see the mentioned Electron issue above.)

On my Ubuntu 24 fresh install and update:

$ if unshare --user true; then echo yes; else echo no; fi
yes

And this check returns yes either I switch sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 or to 1. So, the deb installation never sets SUID on Ubuntu 24.

@pimterry
Copy link
Contributor Author

Do you mean set to 0 to disable it: sysctl -w kernel.apparmor_restrict_unprivileged_userns=0

No, although this is just terminology really. I mean setting to 1, which enables the restriction, which disables user namespaces. It's a bit confusing 😄

I don't have a totally fresh ubuntu install to test with, but on my machine I see:

# Unrestricted, works fine:
> sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
kernel.apparmor_restrict_unprivileged_userns = 0
> unshare --user true
> echo $?
0

# Restricted, fails:
> sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=1
> unshare --user true
unshare: unshare failed: Permission denied
> echo $?
1

That said, this my normal machine, it's not a fresh install and I don't have time right now to set up a fresh VM to explore in depth.

I'd be really surprised that unshare --user true works though, that's literally creating a user namespace (and just running true in it, as a test). The essential idea of this restriction is that users are not allowed to do this, so it should definitely fail. Can you share more details about your setup and all the commands you're running etc?

this change is only until next reboot, while file SUID is permanent

Indeed. The fix here assumes that the system state when you install it is the normal state of your machine. I think that's pretty reasonable though - the only issue is if you allow user namespaces temporarily while installing the package, but then you restrict them again while using it. It's not particularly surprising that this would break things, and I'd guess most people already manually messing with this setting by themselves will realize that.

In general, there are lots of good reasons to not set SUID unnecessarily wherever we can (see bitwarden/clients#5153 for some context) so we should try to avoid this where possible! E.g. for every non-Ubuntu 24 user. Definitely agree it would be good to have something that worked for Ubuntu 24 though, this apparmor issue is super annoying...

I'm not actually the maintainer here, but if there's a better way to detect this to handle the broken Ubuntu case specifically, I'm all for it.

@xmedeko
Copy link

xmedeko commented Oct 24, 2024

@pimterry Ubuntu 24 after reboot:

# Get current value
> sudo sysctl kernel.apparmor_restrict_unprivileged_userns
kernel.apparmor_restrict_unprivileged_userns = 1
> unshare --user true
> echo $?
0

So, even if I set kernel.apparmor_restrict_unprivileged_userns to whatever, I got 0 return value from the unshare --user true test. (I run the fresh Ubuntu install in VirtualBox, but I think it does not affect the result.)

By this advice #8440 (comment) electron-builder has afterInstall param to customize postinst script. I'll give it a try if Ubuntu guys won't fix that bug soon.

@xmedeko
Copy link

xmedeko commented Oct 26, 2024

@pimterry FYI proper solution by Ubuntu guys is to add AppArmor profile, I have filled a feature request for that #8635. Until it's solved, it's possible to do it by afterInstall script, e.g. see gravitational/teleport#43595

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Do we really need a setuid root chrome-sandbox for every platform?
3 participants