The reality is that privsep was always going to be a process. It's taken more than 80 patches to get close to removing rootwrap.

There are other advantages to removing rootwrap, mainly around performance, the integration of library code, and general non-bonkersness (cat to tee to write to a file as root), etc.

There is president in the code to mark calls as undesirable, and others could be marked like that as well, but ultimately someone needs to do an audit and fix things... That's more than one person can reasonably do.

So, who wants to help try and improve this? Patches welcome.

Michael

On Fri., 29 Mar. 2019, 10:26 pm Matthew Booth, <mbooth@redhat.com> wrote:
Privsep is intended to provide some security in depth. The idea is
based on the principal of least privilege. We assume that an attacker
has exploited some bug in Nova and is able to execute arbitrary code.
If privsep is doing its job, the attacker should at least not be able
to perform any privileged operations which Nova does not normally
perform.

For developers, from the spec[1]:

"The intention is to allow slightly more code into the privileged
portion - enough that we now have sufficient “context” to make better
security decisions. For example move from “run chown” to “take
ownership of VM output file”."

Unfortunately, I suspect out of expediency in the initial forklift
from rootwrap, we've lost this critical principal of moving
security-critical logic into privsep itself. Consequently, a brief and
non-exhaustive audit reveals we have privsep functions to do the
following:

fs.py:

* mount anything of any type, including remote storage, anywhere.
* unmount anything
* shred any file or block device, without restriction

path.py:

* read any file or block device, without restriction
* overwrite any existing file or block device

utils.py:

* send any signal to any process

Just the existence of these methods in nova's privsep module
essentially gives the unprivileged nova process unfettered root
access, which entirely defeats the purpose of privsep. As it stands
today, privsep gives us literally nothing. I suspect that it's worse
than rootwrap, in fact. If privsep protection is something we want, we
need to do 2 things:

1. Immediately stop adding or using generic privsep functions.
2. Audit privsep properly for problematic methods, and remove them.

For example, in libvirt.driver.get_console_output() we do
nova.privsep.path.writefile(console_log, 'a+', data). Instead, we
should have, eg,
nova.privsep.libvirt.ensure_console_log_for_instance(instance). This
would determine the instance path from its own secure config (see [1]
again), and touch that file.

We should probably also compile a list of privsep anti-patterns if
there isn't one already to make life simpler for reviewers. For
example, I suggest that no privsep function should take as an argument
a path, or any other reference to a system resource; it should
determine these itself.

I view this as essentially a continuation of the privsep forklift. As
with all such large mechanical changes I expect this to be disruptive
and unloved by reviewers. Is it something we'd be prepared to
prioritise?

Matt

[1] https://specs.openstack.org/openstack/oslo-specs/specs/liberty/privsep.html
--
Matthew Booth
Red Hat OpenStack Engineer, Compute DFG

Phone: +442070094448 (UK)