System-wide sandboxing framework - sandbox-app-launcher

Wayland - Alpine Linux 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?

3 Likes

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.

2 Likes

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*
do
  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} "
  fi
done

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?

No.

1 Like

I think you better set the group of wayland socket to wayland and add applications to wayland group.

2 Likes

I still don’t like the idea of creating any system-wide changes to this. It may be better to enter the sandbox as root with CAP_DAC_OVERRIDE, modify the file permissions within the mount namespace so it doesn’t affect outside of the sandbox and then switch users / drop privileges.

Does Wayland have an equivalent to xhost?

1 Like

Actually, this doesn’t seem to work either. Permissions modified within the namespace seem to be modified outside it too.

1 Like

Perhaps, you want to create a proxy UNIX domain socket?

I don’t know if that would work. Can you test?

Unrelated:

1 Like

I can’t test because I don’t know how to test it.

Let’s assume that I created a proxy UNIX domain socket as wayland user with a proxy program. I would need to find a way to transfer the socket to tmpfs on a new mount namespace and change the owner of the socket.

To do that, the proxy program needs to have access to wayland’s mount namespace and a new wayland client’s mount namespace.

1 Like

Xwayland does AFAICT from this bug fix:

https://cgit.freedesktop.org/xorg/xserver/commit/?id=c4534a3

Also an interesting related thread:

1 Like

What about something like this?

echo "${SUDO_USER} ALL=NOPASSWD: /usr/bin/sudo -H -u ${app_user}" |  EDITOR=tee visudo /etc/sudoers.d/sandbox-app-launcher_${app_user}
2 Likes

visudo is a good idea but insufficient. We can write to a temporary file. Then use visudo as a sanity check. But even if we verified using visudo that the file is valid, writing into /etc/sudoers.d needs to be atomic. I am worried about file system inconsistency. For example, power loss during writing the file. Either the file creation is complete and successful or partial and not really part of the file system.

I.e. can

echo "0123456789" > testfile

result in only ending up

01245

on the hard drive if power is lost in the middle of the operation?

1 Like

References on atomic writes to disk:

https://btrfs.wiki.kernel.org/index.php?title=FAQ&oldid=11521#What_are_the_crash_guarantees_of_overwrite-by-rename.3F

(We currently use ext4 as file system. Not btrfs. Just to show why this might be an issue.)

1 Like
#!/bin/bash

set -x
set -e
set -o pipefail

app_user="test"

sudoers_file_content="## test"

mkdir -p /etc/sandbox-app-launcher

## Non-ideal location for temporary file but required for following atomic rename.
## Should not cross potential file system barriers such as /tmp on a different partition than /etc.
echo "$sudoers_file_content" | tee "/etc/sandbox-app-launcher/sandbox-app-launcher_${app_user}" >/dev/null

## Using '>/dev/null' to hide success messages on stdout.
## Would still show error messages if any on stderr.
SUDO_EDITOR='/bin/false' VISUAL='/bin/false' EDITOR='/bin/false' visudo --strict --check --file "/etc/sandbox-app-launcher/sandbox-app-launcher_${app_user}" >/dev/null

## Atomic rename.
mv "/etc/sandbox-app-launcher/sandbox-app-launcher_${app_user}" "/etc/sudoers.d/sandbox-app-launcher_${app_user}"
1 Like