System-wide sandboxing framework - sandbox-app-launcher

I prefer ALSA to PulseAudio after using both. ALSA is simpler. I can plug PipeWire into ALSA.


An abstract unix socket doesn’t have file permission. Thus, anything that has dbus session bus address can access it. Fortunately, /proc/PID/environ can only be read by the owner of PID.

I didn’t push the boundaries of sandbox-app-launcher / bubblewrap yet but it could be that things as complex as window managers (or virtualizers) could be out of scope.

Could sandbox-app-launcher / bubblewrap be used nested? Similar to how apparmor can migrate from one apparmor profile to another apparmor profile for another application?

Don’t have to technically but as a usability feature it’s much more intuitive this way.

These examples aren’t the best examples. Since these are sufficiently short application names, there is no need for something special.

However, for a few special cases of too long application names [1] or different applications supposed to be using the same application home folder [1] such a “translator” would be good.

Good point.

  • Since sandbox-app-launcher setup does require sudo, injection into app_user variable is not part of the threat model. (Script comment would be useful.)
  • Writing half finished (=broken syntax) files into /etc/sudoers.d/ will break sudo which is difficult to resolve for most users (using booting into recovery mode). (That’s why using visudo is recommended to modify sudo configuration.) Therefore if going for this, writing into /etc/sudoers.d/ needs to be atomic.

What I mean by atomic writes: should there be a power loss, hard drive or file system issue, VM crash or shutdown just in the moment where a sudoers file is written to the disk, it would break the user’s system. Murphy’s law here, anything can go wrong, will go wrong. The more users there are, the more likely one of them would hit this lottery of misfortune.

Perhaps best to write to temporary file first. Can Linux do atomic file copy (to /etc/sudoers.d folder)?

Appending probably not good. We don’t want to append over and over again. Best a new file per user. I.e. /etc/sudoers.d/sandbox-app-launcher_${some_variable}. That would easy uninstallation / removal of users.

Yeah. Bad experiment to play with that.


[1] monero-blockchain-mark-spent-outputs

1 Like

SUID bubblewrap is not nestable. I don’t know whether unprivileged bubblewrap is nestable.

A web browser is far more complex than Sway.
Does every program need to be sandboxed as its own user?

Not sure.

It should work but it’s currently untested. Please try it if you can and report back.

ALSA is still actively updated and isn’t the bane of sandboxes unlike PulseAudio.

I’d suggest that Whonix remove PulseAudio entirely but that’d be for a separate thread.

We mount an empty tmpfs over /tmp. Anything in /tmp outside of the sandbox cannot be accessed from within.

Yes, this is more geared towards end-user applications, not any system software.

bubblewrap can be nested only if using user namespaces. Otherwise, if using setuid, it will disable itself with no_new_privs.

Can’t we just write to /tmp and copy it over?

Yes. Sandboxing programs running as the same user has historically, never seriously worked well. It’s been the cause of many issues with e.g. Flatpak. It’s why Android/iOS have always used separate users.

1 Like

That is an abstract unix domain socket. An abstract UNIX domian socket doesn’t have file permission because it doesn’t reside on file system. If you know the address, any program can access it. You can extract dbus session address from /proc/PID/environ. Fortunately, /proc/PID/environ is readable only by the owner of PID. It is very hard to pick the right address without reading /proc/PID/environ. dbus session address can be considered as a complex password.


Ah, UNIX domain socket restrictions are planned: https://github.com/Whonix/sandbox-app-launcher/blob/master/etc/apparmor.d/abstractions/sandbox-app-launcher#L22

1 Like
$ sudo useradd -m test
$ sudo -u test env WAYLAND_DISPLAY=wayland-1 QT_QPA_PLATFORM=wayland gwenview
error: XDG_RUNTIME_DIR not set in the environment.
Failed to create wl_display (No such file or directory)
qt.qpa.plugin: Could not load the Qt platform plugin "wayland" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: minimal, offscreen, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, xcb.

I think it’s difficult to launch a GUI program as a separate user.

1 Like

X11 works fine currently. I just haven’t tested this on a Wayland system yet. If you could figure out what exactly is causing the issue (maybe some file that needs to be mounted, etc.), that’d be great.

1 Like

https://wiki.alpinelinux.org/wiki/Wayland says

Weston and other compositors require the XDG_RUNTIME_DIR variable to be set.

$XDG_RUNTIME_DIR is /run/user/UID in my case.
Any wayland GUI program needs access to /run/user/wayland's_UID.

$ ls -lhd /run/user/UID
drwx------ 3 UID GID /run/user/UID/
$ ls -lh /run/user/UID
total 0
drwx------ 3 UID GID dbus-1/
srwxr-xr-x 1 UID GID sway-ipc.1000.3905.sock=
srwxr-xr-x 1 UID GID wayland-1=
-rw-r----- 1 UID GID wayland-1.lock

Does this mean wayland applications need to have the same UID as wayland does? Can I tweak the permission of /run/user/UID for wayland’s UID?


In that case let’s go for it? If it can give sandboxed access to audio then that’s a big win IMO. I don’t think any of our users care about the bells and whistles pulseaudio has.

Feel free to open it because it is a large improvement.


XDG_RUNTIME_DIR is set in /etc/X11/Xsession.d/20dbus_xdg-runtime.

Therefore we might have to reconsider /etc/X11/Xsession.d/ parsing (or the wayland equivalent) as per:

1 Like

Not necessarily. We mount an empty tmpfs over /run so those Wayland files are totally inaccessible currently. Something like this might help:

## Mount the wayland files from the user that executes
## sandbox-app-launcher (SUDO_UID) to the app (app_uid)
## sandbox.
app_uid="$(id -u "${app_user}")"
for wl_file in /run/user/${SUDO_UID}/wayland*
  if [ -f "${wl_file}" ]; then
    bwrap_args+="--ro-bind-try ${wl_file} /run/user/${app_uid}/$(echo "${wl_file}" | awk -F "/" '{print $NF}') "
    bwrap_args+="--setenv XDG_RUNTIME_DIR /run/user/${app_uid} "

DAC permissions would likely still be an issue however. A chmod / chown would fix that though.

1 Like

Why don’t you change DAC permissions where they originate?

That would be a system-wide change, possibly worsening security. It’d be difficult to do it seamlessly and without opening up security issues. We could probably change DAC permissions from within the sandbox but that would require CAP_DAC_OVERRIDE and implementing it securely would be complicated.

1 Like

Can bubblewrap change file permission and file owner in a sandbox?


1 Like
[Imprint] [Privacy Policy] [Cookie Policy] [Terms of Use] [E-Sign Consent] [DMCA] [Investors] [Priority Support] [Professional Support]