Add restricted, identifiable bus servers for use in containers
Submitted by Simon McVittie
Assigned to Simon McVittie
In app-container projects like Flatpak, Snap, Firejail and AppImage, there's a need for a confined/contained/sandboxed app to be able to reach services on the normal session and system buses. However, unrestricted access to those buses is scary (and in particular, the session bus is not considered to be a security boundary, so various services there have APIs that are arbitrary code execution).
The motivating use cases right now are:
Portals: Portal authors need to be able to identify whether the container is being contacted by an uncontained process (running with the user's full privileges), or whether it is being contacted by a contained process (in a container created by Flatpak or Snap).
dconf Currently, a contained app either has full read/write access to dconf, or no access. It should have read/write access to its own subtree of dconf configuration space, and no access to the rest.
At the moment, Flatpak runs a D-Bus proxy for each app instance that has access to D-Bus, connects to the appropriate bus on the app's behalf, and passes messages through. That proxy is in a container similar to the actual app instance, but not actually the same container; it is trusted to not pass messages through that it shouldn't pass through. Portals identify the contained app by reading the proxy's
/proc/$pid/root/.flatpak-info, which is Flatpak-specific. Reading through
/proc/$pid/root like that also has an inherent race
condition: if the process exits at exactly the wrong time, and the process ID space (which is only 15 bits) wraps around such that an uncontained or differently-contained process gets the same process ID allocated for it, then the portal would see the differently-contained process's identity instead. Flatpak is effectively trusting the proxy not to exit at a sufficiently inconvenient time.
Meanwhile, Snap does its sandboxing with AppArmor, on kernels where it is enabled both at compile-time (Ubuntu, openSUSE, Debian, Debian derivatives like Tails) and at runtime (Ubuntu, openSUSE and Tails, but not Debian by default). Ubuntu's kernel has extra AppArmor features that haven't yet gone upstream, some of which provide reliable app identification via LSM labels, which
dbus-daemon can learn by querying its
AF_UNIX socket; however, other kernels like the ones in openSUSE and Debian don't have those. The access-control (AppArmor mediation) is implemented in upstream dbus-daemon, but again doesn't work portably: the kernel needs to have the necessary non-upstream features available, and they need to have been enabled at compile time and at runtime. The AppArmor rules are also somewhat inflexible: they are fixed at load time, and do not have access to a lot of useful domain-specific information. They're enough for rules like "allow talking to portals A, B and C", but not really enough for dconf's needs.
I've been discussing this with Allison Lortie and Alexander Larsson at the GTK Hackfest, and we've come up with a plan for obsoleting the Flatpak proxy by enhancing dbus-daemon.
Version: git master