pmatilai · GitHub

The RPM security model where all packages are a free root ticket to the entire system is severely outdated. Especially with file triggers and declarative user/group addition, most packages do need scripts at all, and so it is just an unnecessary risk all around: it's one thing to have eg. malware in an end-user program that "only" affects the users who run that program, it's an entirely different thing to have local root run it on each package install/update. The existing "model" is that you're supposed to have unbounded trust to your vendors, including any third party repositories you may enable. That's a pretty hair-raising proposition when you start thinking about it. Because trust as you may, there are so many points where accidents and oversight can happen and lead to bad outcomes. And then there are the parties you have very little trust for, if at all.

I don't have a fully formed plan here, this is more of a braindump to have something to discuss and build upon.
My proposal is to add a signature based policy mechanism to allow explicit central control over what packages may and may not do - the package signature becomes a central fundamental element of everything instead of just being something you check because the security people tell you to. The signature(s) on a package are mapped to policy files on the system that tell rpm what a package with such-and-such signature(s) are allowed to do.

Some more or less obvious items that should be policy based instead of automatically granted include:

  • per package script execution
  • file trigger execution
  • user/group addition
  • file types (eg device nodes)
  • file ownership and permissions (eg suid user/group)
  • file locations (eg /usr/lib|lib64 vs relatively harmless /usr/bin)
  • package replacement/obsoletion (a random 3rd party package replacing glibc)
  • provide (non-name) capabilities to other packages

Some examples of what comes up when you start building such a thing from the bottom up:

  • "filesystem" package needs to be able to lay down the full directory structure, but beyond that absolutely nothing should touch /home, /proc/, /sys and whatnot.
  • When all the common system "services" like actual systemd services but also caches and such are handled by file triggers from central vendor-owned packages (glibc, systemd etc), only those need the scriptlet/trigger permissions. When other packages trigger those things, they merely execute trusted vendor code.
  • So even for a vendor, there could be multiple layers of policies (needing multiple signatures, but we have them now on rpm-level): the core set like filesystem, systemd etc need wide permissions, but the vast majority of applications do not
  • You might not want to grant a 3rd party repository the means to install system services or libraries at all
  • The policy configuration itself needs to be strongly protected (read: signed) so no random package can inject their own policies, it might call for some kind of "chain of trust" system but also just local admin needs to be able to change and add to it, and lock it down with a signature

Just FWIW, while the idea here very much applies to all RPM based distros, it was initially inspired by poking around in the SailfishOs ecosystem a bit last year. That system leans heavily on app-store level enforcement, but the app-store restrictions are quite severe and limiting, often driving people to 3rd party repositories without realizing the full consequences (that free local root ticket) of it. This kind of policy based system allows for fine-grained control for both the vendor and the user over the current all-or-nothing situation.

Read the original on github.com ↗