Privilege separation (2022)
Continuation of postmarketos#18 (closed), in which we discussed various approaches for implementing privilege separation and landed on AppArmor. Proof of concept was in !2624 (closed). After making the PoC I asked the Alpine TSC to look into this, and they decided against carrying Alpine specific Apparmor profiles, due to the maintenance burden this would bring. Meanwhile in previous months I did a lot of further research but didn't take time to properly write everything down. So here it goes.
Trying AppArmor
After seriously trying AppArmor for some time, I think it is not the right fit for postmarketOS/Alpine. Maintaining profiles would be a huge effort. One has to learn the profile language first, especially what the file permissions mean, read used includes/abstractions to be sure what they do (when actually reading these oftentimes I found they do some things I did not expect) and so on. Don't get me wrong, I think AppArmor is great technology for other distributions who can put in the effort to maintain these profiles, and I respect the people working on it (somebody even found our proof of concept repository and opened bug reports, tried to help us get the profiles right). But just like the Alpine TSC said, I don't think we could handle the effort either.
Also I did not realize that using AppArmor would not help with using XDG Desktop Portal. For example, I tried to make it so that Firefox would not be able to access any files in the user's home directory directly, that it would have to use the XDG Desktop Portal API to save or upload files. I thought I could disallow access to everything in the home dir except for ~/.mozilla/firefox
with AppArmor, set GTK_USE_PORTAL=1
and widget.use-xdg-desktop-portal.*
(like here) and then it would work. I tried it out, and got it so far that in firefox you could not see the files in the home directory (type file:///home/user
in urlbar) but you could see them in the file open dialog as expected. But actually accessing the files through the portal did not work - the reason is I only got the file chooser working, but not the document portal. Somebody had a similar misunderstanding in xdg-desktop-portal#680. So it's not like you disallow access to everything but ~/.mozilla/firefox
with e.g. AppArmor and xdg-desktop-portal does the rest. You would need an implementation of the Documents portal, that is from what I found only in flatpak and snap. The most you could do with AppArmor alone in regards to limiting access to the user's home directory is disallowing everything but ~/.mozilla/firefox
and ~/Downloads
. But that has of course the serious disadvantage that you can't simply upload a file from any other directory, say a picture you took with the camera (and also Downloads would be shared between multiple applications). I think we need a solution in postmarketOS where at least we have working document portals.
Goals revisited
I went back to the drawing board and listed goals I think we should meet for privilege separation in postmarketOS.
- lock down apps/daemons with biggest attack surfaces
- examples of relevant apps: browser, chat/sms/mms related, bluetooth, ...
- examples of not so relevant apps: terminal, calculator, megapixels, welcome app
- make the profiles well-maintainable
- should be possible to read them without effort
- every profile should only have a few lines of code
- no allow-list for /usr, leads to complex profiles and breaks too often
- make xdg desktop portals work
- proper access limitation to data in home dir
- lots of other useful portals, such as the one that allows camera etc.
Trying to use flatpak to set up sandboxes only
As I understand it, xdg-desktop-portal was implemented by the flatpak folks and then later adapted to work for snaps too.
I wish it was possible to simply use flatpak's sandboxing with portals with native alpine packages, instead of using the flatpak (or snap) app format. Then we would still have the benefits of using alpine's minimal packages, the very fast and simple apk/abuild and APKBUILD format, the infrastructure where we can easily search through packages and find the related APKBUILD, of alpine/pmOS having the last say on packaging and not vendors and being sure that there's only free software in the apps. Then we could also use the sandboxing for daemons, not just for apps.
I tried to make a dummy flatpak app that would mount everything but the home dir from the host OS inside the virtual filesystem... but /lib, /usr are blacklisted as documented here and there are more problems. With a lot of further hacks on top it might work, but it's not a good solution, won't be maintainable in the long run either. We would need to maintain a fork of flatpak with a lot of modifications.
Bubblewrap
Flatpak is built on top of bubblewrap. So the other approach to using portals like flatpak without actually using flatpak would be using bubblewrap and writing shell scripts that emulate how flatpak would call it internally. Something like this:
#!/bin/sh
exec bwrap --ro-bind /usr /usr \
--dir /tmp \
--dir /var \
... \
/usr/bin/path-to-real-application
I brought this idea up earlier, and Clayton and Alexey also suggested this at some point. Back then I discarded it so I would not reinvent the wheel, assuming that AppArmor would solve the problem more elegantly. But it didn't solve this problem, especially I wasn't able to use portals with it as I learned it now. So actually this problem of sandboxing native applications in a way that they can use xdg-desktop-portal is a wheel that has not been invented yet.
I think these launch scripts would be relatively easy to maintain. The big problem is that to make desktop portals work, we need more glue than just this one function call. But after trying everything above, getting this working and maintaining it seems more feasible than getting flatpak to run native apps.
So here is where I am with this problem, next I would try to use bwrap with xdg-desktop-portal, but without using flatpak. Maybe a wrapper around bwrap that sets up the portals and re-uses code from flatpak. I'm currently focused on other topics, but this is the current state of things for future reference.
EDIT 2023-10-22: I was pointed at a related xdg-desktop-portal PR "Allow portal access non-flatpak sandboxes": https://github.com/flatpak/xdg-desktop-portal/pull/741