Applications should not have access to data of other applications or to user's private data unless user allows them. Isn't this an obvious need? But every program we launch has full access to our $HOME dir, to our mic and cam. Most users will not even notice if (for example) Skype start sending somewhere their private files or streaming sound from their mic.
I'm looking for ways to fix this. Feel free to suggest anything even if your method implies writing SELinux policies, LSM modules, kernel patches, switching to another UNIX-like OS.
Here is some ideas I had and reasons I rejected them:
- We create new unix users for every untrusted app. We use SUID bit to make that app always run as it's user. Bad. Because we need to blacklist every app we don't trust and every new app we install. Tons of work, easy to miss something. Also binaries may lose SUID flag when we upgrade/reinstall app. In addition, there is problem with child processes: in theory, apps that don't have some permission, can use other app to achieve their goal. And if we don't use SUID, it will be hard to remember that we need to use "su" to start every untrusted app.
- We use SELinux domain transition to confine untrusted apps. Also bad. Same problem as with #1. We need to write/update/inject SELinux policies for every app we don't trust. I want apps to have no special access by default, not full access.
- We create new "trusted" unix users for trusted apps. We can use groups to implement various categories of private data: photos, notes etc. But we can't use SUID and we need manually switch to that user before starting app (with password). Problem of this option is child processes. We can't allow all child processes of trusted program to be trusted (if we open media file in trusted file manager, we don't want media player to inherit trusted status of file manager). But we also can't allow all child processes to drop their permissions to default. Also bad!
- We use SELinux to implement "trusted" domains for every trusted app. We can't use automatic domain transition in this case. So we need to switch domain with password. This option is slightly better than #3 because we can forbid launching untrusted apps in such trusted domains. But still bad and uncomfortable.
- If we think more, we are starting to see that we can't bind permissions to executible binaries at all. For example, Python interpreter may need different permissions depending on script it runs. So we can forget about options #1 and #2.
- We can make our own LSM module (like SELinux). But how it is supposed to work? Not sure I have ideas. Interactive mode? Asking user's permission every time some process attempts to read private files? Or should we take some ideas from "lomac" (low watermark) model? Say, reading untrusted data makes environment tainted and blocks it from reading private data.
- Userspace daemon + LD_PRELOAD library? In this case, apps don't have access to private files by default, but they can contact privileged daemon and ask it to open such files and pass file descriptor. This is doable and will look like old "interactive firewalls" for Windows.
More ideas? Please tell me you know ready-made solution :)