Expand the "secmodel" XML fragment of "host" with a sequence of
baselabel's which describe the default security context used by
libvirt with a specific security model and virtualization type:
<secmodel>
<model>selinux</model>
<doi>0</doi>
<baselabel type='kvm'>system_u:system_r:svirt_t:s0</baselabel>
<baselabel type='qemu'>system_u:system_r:svirt_t:s0</baselabel>
</secmodel>
<secmodel>
<model>dac</model>
<doi>0</doi>
<baselabel type='kvm'>0:0</baselabel>
<baselabel type='qemu'>0:0</baselabel>
</secmodel>
"baselabel" is driver-specific information, e.g. in the DAC security
model, it indicates USER_ID:GROUP_ID.
Signed-off-by: Giuseppe Scrivano <gscrivan(a)redhat.com>
---
src/conf/capabilities.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++--
src/conf/capabilities.h | 14 +++++++++++
src/libvirt_private.syms | 1 +
src/qemu/qemu_conf.c | 11 ++++++---
4 files changed, 81 insertions(+), 5 deletions(-)
diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
index 1acc936..b0e2ff9 100644
--- a/src/conf/capabilities.c
+++ b/src/conf/capabilities.c
@@ -184,6 +184,20 @@ virCapabilitiesFreeNUMAInfo(virCapsPtr caps)
}
static void
+virCapabilitiesFreeSecModel(virCapsHostSecModelPtr secmodel)
+{
+ size_t i;
+ for (i = 0; i < secmodel->nlabels; i++) {
+ VIR_FREE(secmodel->labels[i].type);
+ VIR_FREE(secmodel->labels[i].label);
+ }
+
+ VIR_FREE(secmodel->labels);
+ VIR_FREE(secmodel->model);
+ VIR_FREE(secmodel->doi);
+}
+
+static void
virCapabilitiesDispose(void *object)
{
virCapsPtr caps = object;
@@ -204,8 +218,7 @@ virCapabilitiesDispose(void *object)
VIR_FREE(caps->host.migrateTrans);
for (i = 0; i < caps->host.nsecModels; i++) {
- VIR_FREE(caps->host.secModels[i].model);
- VIR_FREE(caps->host.secModels[i].doi);
+ virCapabilitiesFreeSecModel(&caps->host.secModels[i]);
}
VIR_FREE(caps->host.secModels);
@@ -507,6 +520,44 @@ virCapabilitiesAddGuestFeature(virCapsGuestPtr guest,
}
/**
+ * virCapabilitiesHostSecModelAddBaseLabel
+ * @secmodel: Security model to add a base label for
+ * @type: virtualization type
+ * @label: base label
+ *
+ * Returns non-zero on error.
+ */
+extern int
+virCapabilitiesHostSecModelAddBaseLabel(virCapsHostSecModelPtr secmodel,
+ const char *type,
+ const char *label)
+{
+ char *t = NULL, *l = NULL;
+
+ if (type == NULL || label == NULL)
+ return -1;
+
+ if (VIR_STRDUP(t, type) < 0)
+ goto no_memory;
+
+ if (VIR_STRDUP(l, label) < 0)
+ goto no_memory;
+
+ if (VIR_EXPAND_N(secmodel->labels, secmodel->nlabels, 1) < 0)
+ goto no_memory;
+
+ secmodel->labels[secmodel->nlabels - 1].type = t;
+ secmodel->labels[secmodel->nlabels - 1].label = l;
+
+ return 0;
+
+no_memory:
+ VIR_FREE(l);
+ VIR_FREE(t);
+ return -1;
+}
+
+/**
* virCapabilitiesSupportsGuestArch:
* @caps: capabilities to query
* @arch: Architecture to search for
@@ -826,6 +877,11 @@ virCapabilitiesFormatXML(virCapsPtr caps)
caps->host.secModels[i].model);
virBufferAsprintf(&xml, " <doi>%s</doi>\n",
caps->host.secModels[i].doi);
+ for (j = 0; j < caps->host.secModels[i].nlabels; j++) {
+ virBufferAsprintf(&xml, " <baselabel
type='%s'>%s</baselabel>\n",
+ caps->host.secModels[i].labels[j].type,
+ caps->host.secModels[i].labels[j].label);
+ }
virBufferAddLit(&xml, " </secmodel>\n");
}
diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
index 88ec454..5bc7bb5 100644
--- a/src/conf/capabilities.h
+++ b/src/conf/capabilities.h
@@ -104,11 +104,20 @@ struct _virCapsHostNUMACell {
virCapsHostNUMACellCPUPtr cpus;
};
+typedef struct _virCapsHostSecModelLabel virCapsHostSecModelLabel;
+typedef virCapsHostSecModelLabel *virCapsHostSecModelLabelPtr;
+struct _virCapsHostSecModelLabel {
+ char *type;
+ char *label;
+};
+
typedef struct _virCapsHostSecModel virCapsHostSecModel;
typedef virCapsHostSecModel *virCapsHostSecModelPtr;
struct _virCapsHostSecModel {
char *model;
char *doi;
+ size_t nlabels;
+ virCapsHostSecModelLabelPtr labels;
};
typedef struct _virCapsHost virCapsHost;
@@ -225,6 +234,11 @@ virCapabilitiesAddGuestFeature(virCapsGuestPtr guest,
int toggle);
extern int
+virCapabilitiesHostSecModelAddBaseLabel(virCapsHostSecModelPtr secmodel,
+ const char *type,
+ const char *label);
+
+extern int
virCapabilitiesSupportsGuestArch(virCapsPtr caps,
virArch arch);
extern int
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index aea7e94..cdf9e58 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -58,6 +58,7 @@ virCapabilitiesFormatXML;
virCapabilitiesFreeMachines;
virCapabilitiesFreeNUMAInfo;
virCapabilitiesGetCpusForNodemask;
+virCapabilitiesHostSecModelAddBaseLabel;
virCapabilitiesNew;
virCapabilitiesSetHostCPU;
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 1f57f72..71dbb27 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -563,7 +563,7 @@ virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver)
virCapsPtr caps;
virSecurityManagerPtr *sec_managers = NULL;
/* Security driver data */
- const char *doi, *model;
+ const char *doi, *model, *label;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
/* Basic host arch / guest machine capabilities */
@@ -589,11 +589,16 @@ virCapsPtr virQEMUDriverCreateCapabilities(virQEMUDriverPtr driver)
goto error;
for (i = 0; sec_managers[i]; i++) {
+ virCapsHostSecModelPtr sm = &caps->host.secModels[i];
doi = virSecurityManagerGetDOI(sec_managers[i]);
model = virSecurityManagerGetModel(sec_managers[i]);
- if (VIR_STRDUP(caps->host.secModels[i].model, model) < 0 ||
- VIR_STRDUP(caps->host.secModels[i].doi, doi) < 0)
+ label = virSecurityManagerGetBaseLabel(sec_managers[i]);
+ if (VIR_STRDUP(sm->model, model) < 0 ||
+ VIR_STRDUP(sm->doi, doi) < 0 ||
+ virCapabilitiesHostSecModelAddBaseLabel(sm, "kvm", label) < 0
||
+ virCapabilitiesHostSecModelAddBaseLabel(sm, "qemu", label) < 0)
goto error;
+
VIR_DEBUG("Initialized caps for security driver \"%s\" with
"
"DOI \"%s\"", model, doi);
}
--
1.8.3.1