]> git.ipfire.org Git - thirdparty/libvirt.git/commit
security_stack: Perform rollback if one of stacked drivers fails
authorMichal Privoznik <mprivozn@redhat.com>
Wed, 11 Sep 2019 09:19:06 +0000 (11:19 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 14 Oct 2019 15:23:19 +0000 (17:23 +0200)
commit9d03e9adf1776104290e7c7d3368e58998f27987
tree17d1eaa6bd6a7b22423b5ddba1d43d4cd2b684d9
parentcd355a526ff239eed24b50959ffb21e390724b74
security_stack: Perform rollback if one of stacked drivers fails

In order to have multiple security drivers hidden under one
virSecurity* call, we have virSecurityStack driver which holds a
list of registered security drivers and for every virSecurity*
call it iterates over the list and calls corresponding callback
in real security drivers. For instance, for
virSecurityManagerSetAllLabel() it calls
domainSetSecurityAllLabel callback sequentially in NOP, DAC and
(possibly) SELinux or AppArmor drivers. This works just fine if
the callback from every driver returns success. Problem arises
when one of the drivers fails. For instance, aforementioned
SetAllLabel() succeeds for DAC but fails in SELinux in which
case all files that DAC relabelled are now owned by qemu:qemu (or
whomever runs qemu) and thus permissions are leaked. This is even
more visible with XATTRs which remain set for DAC.

The solution is to perform a rollback on failure, i.e. call
opposite action on drivers that succeeded.

I'm providing rollback only for set calls and intentionally
omitting restore calls for two reasons:

1) restore calls are less likely to fail (they merely remove
XATTRs and chown()/setfilecon() file - all of these operations
succeeded in set call),

2) we are not really interested in restore failures - in a very
few places we check for retval of a restore function we do so
only to print a warning.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1740024

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Cole Robinson <crobinso@redhat.com>
src/security/security_stack.c