提交 62f3d8ad 编写于 作者: M Michal Privoznik

security: Introduce VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP flag

Our decision whether to remember seclabel for a disk image
depends on a few factors. If the image is readonly or shared or
not the chain top the remembering is suppressed for the image.
However, the virSecurityManagerSetImageLabel() is too low level
to determine whether passed @src is chain top or not. Even though
the function has the @parent argument it does not necessarily
reflect the chain top - it only points to the top level image in
the chain we want to relabel and not to the topmost image of the
whole chain. And this can't be derived from the passed domain
definition reliably neither - in some cases (like snapshots or
block copy) the @src is added to the definition only after the
operation succeeded. Therefore, introduce a flag which callers
can use to help us with the decision.
Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
Reviewed-by: NPeter Krempa <pkrempa@redhat.com>
上级 9e85e118
...@@ -889,14 +889,14 @@ static int ...@@ -889,14 +889,14 @@ static int
virSecurityDACSetImageLabelInternal(virSecurityManagerPtr mgr, virSecurityDACSetImageLabelInternal(virSecurityManagerPtr mgr,
virDomainDefPtr def, virDomainDefPtr def,
virStorageSourcePtr src, virStorageSourcePtr src,
virStorageSourcePtr parent) virStorageSourcePtr parent,
bool isChainTop)
{ {
virSecurityLabelDefPtr secdef; virSecurityLabelDefPtr secdef;
virSecurityDeviceLabelDefPtr disk_seclabel; virSecurityDeviceLabelDefPtr disk_seclabel;
virSecurityDeviceLabelDefPtr parent_seclabel = NULL; virSecurityDeviceLabelDefPtr parent_seclabel = NULL;
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr); virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
bool remember; bool remember;
bool is_toplevel = parent == src || parent->externalDataStore == src;
uid_t user; uid_t user;
gid_t group; gid_t group;
...@@ -954,7 +954,7 @@ virSecurityDACSetImageLabelInternal(virSecurityManagerPtr mgr, ...@@ -954,7 +954,7 @@ virSecurityDACSetImageLabelInternal(virSecurityManagerPtr mgr,
* but the top layer, or read only image, or disk explicitly * but the top layer, or read only image, or disk explicitly
* marked as shared. * marked as shared.
*/ */
remember = is_toplevel && !src->readonly && !src->shared; remember = isChainTop && !src->readonly && !src->shared;
return virSecurityDACSetOwnership(mgr, src, NULL, user, group, remember); return virSecurityDACSetOwnership(mgr, src, NULL, user, group, remember);
} }
...@@ -970,7 +970,9 @@ virSecurityDACSetImageLabelRelative(virSecurityManagerPtr mgr, ...@@ -970,7 +970,9 @@ virSecurityDACSetImageLabelRelative(virSecurityManagerPtr mgr,
virStorageSourcePtr n; virStorageSourcePtr n;
for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) { 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; return -1;
if (n->externalDataStore && if (n->externalDataStore &&
...@@ -983,6 +985,8 @@ virSecurityDACSetImageLabelRelative(virSecurityManagerPtr mgr, ...@@ -983,6 +985,8 @@ virSecurityDACSetImageLabelRelative(virSecurityManagerPtr mgr,
if (!(flags & VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN)) if (!(flags & VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN))
break; break;
flags &= ~VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP;
} }
return 0; return 0;
...@@ -2114,7 +2118,8 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr, ...@@ -2114,7 +2118,8 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr,
if (virDomainDiskGetType(def->disks[i]) == VIR_STORAGE_TYPE_DIR) if (virDomainDiskGetType(def->disks[i]) == VIR_STORAGE_TYPE_DIR)
continue; continue;
if (virSecurityDACSetImageLabel(mgr, def, def->disks[i]->src, 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; return -1;
} }
......
...@@ -151,6 +151,10 @@ virSecurityManagerPtr* virSecurityManagerGetNested(virSecurityManagerPtr mgr); ...@@ -151,6 +151,10 @@ virSecurityManagerPtr* virSecurityManagerGetNested(virSecurityManagerPtr mgr);
typedef enum { typedef enum {
VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN = 1 << 0, 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; } virSecurityDomainImageLabelFlags;
int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr, int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr,
......
...@@ -1824,7 +1824,8 @@ static int ...@@ -1824,7 +1824,8 @@ static int
virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr, virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
virDomainDefPtr def, virDomainDefPtr def,
virStorageSourcePtr src, virStorageSourcePtr src,
virStorageSourcePtr parent) virStorageSourcePtr parent,
bool isChainTop)
{ {
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr); virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
virSecurityLabelDefPtr secdef; virSecurityLabelDefPtr secdef;
...@@ -1832,7 +1833,6 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr, ...@@ -1832,7 +1833,6 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
virSecurityDeviceLabelDefPtr parent_seclabel = NULL; virSecurityDeviceLabelDefPtr parent_seclabel = NULL;
char *use_label = NULL; char *use_label = NULL;
bool remember; bool remember;
bool is_toplevel = parent == src || parent->externalDataStore == src;
g_autofree char *vfioGroupDev = NULL; g_autofree char *vfioGroupDev = NULL;
const char *path = src->path; const char *path = src->path;
int ret; int ret;
...@@ -1856,7 +1856,7 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr, ...@@ -1856,7 +1856,7 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
* but the top layer, or read only image, or disk explicitly * but the top layer, or read only image, or disk explicitly
* marked as shared. * marked as shared.
*/ */
remember = is_toplevel && !src->readonly && !src->shared; remember = isChainTop && !src->readonly && !src->shared;
disk_seclabel = virStorageSourceGetSecurityLabelDef(src, disk_seclabel = virStorageSourceGetSecurityLabelDef(src,
SECURITY_SELINUX_NAME); SECURITY_SELINUX_NAME);
...@@ -1873,7 +1873,7 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr, ...@@ -1873,7 +1873,7 @@ virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
return 0; return 0;
use_label = parent_seclabel->label; use_label = parent_seclabel->label;
} else if (is_toplevel) { } else if (parent == src || parent->externalDataStore == src) {
if (src->shared) { if (src->shared) {
use_label = data->file_context; use_label = data->file_context;
} else if (src->readonly) { } else if (src->readonly) {
...@@ -1930,7 +1930,9 @@ virSecuritySELinuxSetImageLabelRelative(virSecurityManagerPtr mgr, ...@@ -1930,7 +1930,9 @@ virSecuritySELinuxSetImageLabelRelative(virSecurityManagerPtr mgr,
virStorageSourcePtr n; virStorageSourcePtr n;
for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) { 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; return -1;
if (n->externalDataStore && if (n->externalDataStore &&
...@@ -1943,6 +1945,8 @@ virSecuritySELinuxSetImageLabelRelative(virSecurityManagerPtr mgr, ...@@ -1943,6 +1945,8 @@ virSecuritySELinuxSetImageLabelRelative(virSecurityManagerPtr mgr,
if (!(flags & VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN)) if (!(flags & VIR_SECURITY_DOMAIN_IMAGE_LABEL_BACKING_CHAIN))
break; break;
flags &= ~VIR_SECURITY_DOMAIN_IMAGE_PARENT_CHAIN_TOP;
} }
return 0; return 0;
...@@ -3146,7 +3150,8 @@ virSecuritySELinuxSetAllLabel(virSecurityManagerPtr mgr, ...@@ -3146,7 +3150,8 @@ virSecuritySELinuxSetAllLabel(virSecurityManagerPtr mgr,
continue; continue;
} }
if (virSecuritySELinuxSetImageLabel(mgr, def, def->disks[i]->src, 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; return -1;
} }
/* XXX fixme process def->fss if relabel == true */ /* XXX fixme process def->fss if relabel == true */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册