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)