Here is the problem: If all disks had XATTRs (i.e. domains using
them were started with owner remembering turned on) then
refcounting implemented in XATTRs would work nicely and we could
set the whole backing chain and restore it later. But world is
not that simple. As soon as there is one domain that was started
with the feature turned off (or simply by older libvirt), the
XATTR refounting does not reflect the actual number of uses by
running domains and therefore any attempt to restore might cut
off the old domain.
There is no simple way around this. Except artificially turning
the feature off for the rest of the backing chain.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/security/security_dac.c | 3 ++-
src/security/security_selinux.c | 13 +++++++------
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index e47f0343e7..91e91e378e 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -911,7 +911,8 @@ virSecurityDACSetImageLabelInternal(virSecurityManagerPtr mgr,
return -1;
}
- return virSecurityDACSetOwnership(mgr, src, NULL, user, group, true);
+ /* Remember label only for the top level image. */
+ return virSecurityDACSetOwnership(mgr, src, NULL, user, group, src == parent);
}
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index e696311b09..10585e9f8c 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1819,6 +1819,7 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
virSecurityLabelDefPtr secdef;
virSecurityDeviceLabelDefPtr disk_seclabel;
virSecurityDeviceLabelDefPtr parent_seclabel = NULL;
+ const bool remember = src == parent;
int ret;
if (!src->path || !virStorageSourceIsLocalStorage(src))
@@ -1839,29 +1840,29 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr
mgr,
return 0;
ret = virSecuritySELinuxSetFilecon(mgr, src->path,
- disk_seclabel->label, true);
+ disk_seclabel->label, remember);
} else if (parent_seclabel && (!parent_seclabel->relabel ||
parent_seclabel->label)) {
if (!parent_seclabel->relabel)
return 0;
ret = virSecuritySELinuxSetFilecon(mgr, src->path,
- parent_seclabel->label, true);
+ parent_seclabel->label, remember);
} else if (!parent || parent == src) {
if (src->shared) {
ret = virSecuritySELinuxSetFileconOptional(mgr,
src->path,
data->file_context,
- true);
+ remember);
} else if (src->readonly) {
ret = virSecuritySELinuxSetFileconOptional(mgr,
src->path,
data->content_context,
- true);
+ remember);
} else if (secdef->imagelabel) {
ret = virSecuritySELinuxSetFileconOptional(mgr,
src->path,
secdef->imagelabel,
- true);
+ remember);
} else {
ret = 0;
}
@@ -1869,7 +1870,7 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
ret = virSecuritySELinuxSetFileconOptional(mgr,
src->path,
data->content_context,
- true);
+ remember);
}
if (ret == 1 && !disk_seclabel) {
--
2.19.2