virSecurityDACSetImageLabelInternal(virSecurityManagerPtr mgr,
virDomainDefPtr def,
virStorageSourcePtr src,
- virStorageSourcePtr parent)
+ virStorageSourcePtr parent,
+ bool isChainTop)
{
virSecurityLabelDefPtr secdef;
virSecurityDeviceLabelDefPtr disk_seclabel;
virSecurityDeviceLabelDefPtr parent_seclabel = NULL;
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
bool remember;
- bool is_toplevel = parent == src || parent->externalDataStore == src;
uid_t user;
gid_t group;
* but the top layer, or read only image, or disk explicitly
* marked as shared.
*/
- remember = is_toplevel && !src->readonly && !src->shared;
+ remember = isChainTop && !src->readonly && !src->shared;
return virSecurityDACSetOwnership(mgr, src, NULL, user, group, remember);
}
virStorageSourcePtr n;
for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) {
- if (virSecurityDACSetImageLabelInternal(mgr, def, n, parent) < 0)
+ const bool isChainTop = flags & VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP;
+
+ if (virSecurityDACSetImageLabelInternal(mgr, def, n, parent, isChainTop) < 0)
return -1;
if (n->externalDataStore &&
if (!(flags & VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN))
break;
+
+ flags &= ~VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP;
}
return 0;
if (virDomainDiskGetType(def->disks[i]) == VIR_STORAGE_TYPE_DIR)
continue;
if (virSecurityDACSetImageLabel(mgr, def, def->disks[i]->src,
- VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN) < 0)
+ VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN |
+ VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP) < 0)
return -1;
}
typedef enum {
VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN = 1 << 0,
+ /* The VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP should be set if the
+ * image passed to virSecurityManagerSetImageLabel() is the top parent of
+ * the whole backing chain. */
+ VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP = 1 << 1,
} virSecurityDomainImageLabelFlags;
int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr,
virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
virDomainDefPtr def,
virStorageSourcePtr src,
- virStorageSourcePtr parent)
+ virStorageSourcePtr parent,
+ bool isChainTop)
{
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
virSecurityLabelDefPtr secdef;
virSecurityDeviceLabelDefPtr parent_seclabel = NULL;
char *use_label = NULL;
bool remember;
- bool is_toplevel = parent == src || parent->externalDataStore == src;
g_autofree char *vfioGroupDev = NULL;
const char *path = src->path;
int ret;
* but the top layer, or read only image, or disk explicitly
* marked as shared.
*/
- remember = is_toplevel && !src->readonly && !src->shared;
+ remember = isChainTop && !src->readonly && !src->shared;
disk_seclabel = virStorageSourceGetSecurityLabelDef(src,
SECURITY_SELINUX_NAME);
return 0;
use_label = parent_seclabel->label;
- } else if (is_toplevel) {
+ } else if (parent == src || parent->externalDataStore == src) {
if (src->shared) {
use_label = data->file_context;
} else if (src->readonly) {
virStorageSourcePtr n;
for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) {
- if (virSecuritySELinuxSetImageLabelInternal(mgr, def, n, parent) < 0)
+ const bool isChainTop = flags & VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP;
+
+ if (virSecuritySELinuxSetImageLabelInternal(mgr, def, n, parent, isChainTop) < 0)
return -1;
if (n->externalDataStore &&
if (!(flags & VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN))
break;
+
+ flags &= ~VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP;
}
return 0;
continue;
}
if (virSecuritySELinuxSetImageLabel(mgr, def, def->disks[i]->src,
- VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN) < 0)
+ VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN |
+ VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP) < 0)
return -1;
}
/* XXX fixme process def->fss if relabel == true */