---
src/security/security_apparmor.c | 112 ++++++++++----
src/security/security_dac.c | 320 ++++++++++++++++++++++++++++++++++----
src/security/security_manager.c | 99 +++++++++---
src/security/security_manager.h | 8 +-
src/security/security_selinux.c | 249 +++++++++++++++++++++---------
src/security/security_stack.c | 235 +++++++++++++++++++---------
src/security/security_stack.h | 13 ++
7 files changed, 803 insertions(+), 233 deletions(-)
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 2d05fd0..d5d41f6 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -262,9 +262,13 @@ reload_profile(virSecurityManagerPtr mgr,
const char *fn,
bool append)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
int rc = -1;
char *profile_name = NULL;
+ const virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(
+ def, SECURITY_APPARMOR_NAME);
+
+ if (!secdef)
+ return rc;
if (secdef->norelabel)
return 0;
@@ -298,7 +302,12 @@ AppArmorSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
virDomainDefPtr def = ptr->def;
if (reload_profile(ptr->mgr, def, file, true) < 0) {
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ const virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(
+ def, SECURITY_APPARMOR_NAME);
+ if (!secdef) {
+ virReportOOMError();
+ return -1;
+ }
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
"\'%s\'"),
@@ -316,7 +325,12 @@ AppArmorSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
virDomainDefPtr def = ptr->def;
if (reload_profile(ptr->mgr, def, file, true) < 0) {
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ const virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(
+ def, SECURITY_APPARMOR_NAME);
+ if (!secdef) {
+ virReportOOMError();
+ return -1;
+ }
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
"\'%s\'"),
@@ -398,18 +412,23 @@ AppArmorGenSecurityLabel(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
{
int rc = -1;
char *profile_name = NULL;
+ virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(def,
+ SECURITY_APPARMOR_NAME);
- if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
+ if (!secdef)
+ return -1;
+
+ if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
return 0;
- if (def->seclabel.baselabel) {
+ if (secdef->baselabel) {
virSecurityReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("Cannot set a base label with
AppArmour"));
return rc;
}
- if ((def->seclabel.label) ||
- (def->seclabel.model) || (def->seclabel.imagelabel)) {
+ if ((secdef->label) ||
+ (secdef->model) || (secdef->imagelabel)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
"%s",
_("security label already defined for VM"));
@@ -419,31 +438,31 @@ AppArmorGenSecurityLabel(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
if ((profile_name = get_profile_name(def)) == NULL)
return rc;
- def->seclabel.label = strndup(profile_name, strlen(profile_name));
- if (!def->seclabel.label) {
+ secdef->label = strndup(profile_name, strlen(profile_name));
+ if (!secdef->label) {
virReportOOMError();
goto clean;
}
/* set imagelabel the same as label (but we won't use it) */
- def->seclabel.imagelabel = strndup(profile_name,
- strlen(profile_name));
- if (!def->seclabel.imagelabel) {
+ secdef->imagelabel = strndup(profile_name,
+ strlen(profile_name));
+ if (!secdef->imagelabel) {
virReportOOMError();
goto err;
}
- def->seclabel.model = strdup(SECURITY_APPARMOR_NAME);
- if (!def->seclabel.model) {
+ secdef->model = strdup(SECURITY_APPARMOR_NAME);
+ if (!secdef->model) {
virReportOOMError();
goto err;
}
/* Now that we have a label, load the profile into the kernel. */
- if (load_profile(mgr, def->seclabel.label, def, NULL, false) < 0) {
+ if (load_profile(mgr, secdef->label, def, NULL, false) < 0) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot load AppArmor profile "
- "\'%s\'"), def->seclabel.label);
+ "\'%s\'"), secdef->label);
goto err;
}
@@ -451,9 +470,9 @@ AppArmorGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
goto clean;
err:
- VIR_FREE(def->seclabel.label);
- VIR_FREE(def->seclabel.imagelabel);
- VIR_FREE(def->seclabel.model);
+ VIR_FREE(secdef->label);
+ VIR_FREE(secdef->imagelabel);
+ VIR_FREE(secdef->model);
clean:
VIR_FREE(profile_name);
@@ -465,7 +484,12 @@ static int
AppArmorSetSecurityAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def, const char *stdin_path)
{
- if (def->seclabel.norelabel)
+ virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(def,
+ SECURITY_APPARMOR_NAME);
+ if (!secdef)
+ return -1;
+
+ if (secdef->norelabel)
return 0;
/* Reload the profile if stdin_path is specified. Note that
@@ -518,7 +542,10 @@ static int
AppArmorReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainDefPtr def)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ const virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(def,
+ SECURITY_APPARMOR_NAME);
+ if (!secdef)
+ return -1;
VIR_FREE(secdef->model);
VIR_FREE(secdef->label);
@@ -533,8 +560,12 @@ AppArmorRestoreSecurityAllLabel(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
virDomainDefPtr def,
int migrated ATTRIBUTE_UNUSED)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
int rc = 0;
+ const virSecurityLabelDefPtr secdef =
+ virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
+
+ if (!secdef)
+ return -1;
if (secdef->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
if ((rc = remove_profile(secdef->label)) != 0) {
@@ -552,9 +583,13 @@ AppArmorRestoreSecurityAllLabel(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
static int
AppArmorSetSecurityProcessLabel(virSecurityManagerPtr mgr, virDomainDefPtr def)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
int rc = -1;
char *profile_name = NULL;
+ const virSecurityLabelDefPtr secdef =
+ virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
+
+ if (!secdef)
+ return -1;
if ((profile_name = get_profile_name(def)) == NULL)
return rc;
@@ -621,9 +656,13 @@ static int
AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def, virDomainDiskDefPtr disk)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
int rc = -1;
char *profile_name;
+ const virSecurityLabelDefPtr secdef =
+ virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
+
+ if (!secdef)
+ return -1;
if (secdef->norelabel)
return 0;
@@ -666,7 +705,11 @@ static int
AppArmorSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainDefPtr def)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ const virSecurityLabelDefPtr secdef =
+ virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
+
+ if (!secdef)
+ return -1;
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) {
if (use_apparmor() < 0 || profile_status(secdef->label, 0) < 0) {
@@ -694,9 +737,13 @@ AppArmorSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
virDomainHostdevDefPtr dev)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
struct SDPDOP *ptr;
int ret = -1;
+ const virSecurityLabelDefPtr secdef =
+ virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
+
+ if (!secdef)
+ return -1;
if (secdef->norelabel)
return 0;
@@ -756,7 +803,12 @@ AppArmorRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ const virSecurityLabelDefPtr secdef =
+ virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
+
+ if (!secdef)
+ return -1;
+
if (secdef->norelabel)
return 0;
@@ -789,7 +841,11 @@ AppArmorSetImageFDLabel(virSecurityManagerPtr mgr,
char *proc = NULL;
char *fd_path = NULL;
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ const virSecurityLabelDefPtr secdef =
+ virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
+
+ if (!secdef)
+ return -1;
if (secdef->imagelabel == NULL)
return 0;
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 470861d..0badafb 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -33,6 +33,7 @@
#include "storage_file.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
+#define SECURITY_DAC_NAME "dac"
typedef struct _virSecurityDACData virSecurityDACData;
typedef virSecurityDACData *virSecurityDACDataPtr;
@@ -64,6 +65,132 @@ void virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
priv->dynamicOwnership = dynamicOwnership;
}
+static
+int parseIds(const char *label, uid_t *uidPtr, gid_t *gidPtr)
+{
+ uid_t uid;
+ gid_t gid;
+ char *endptr = NULL;
+
+ if (label == NULL)
+ return -1;
+
+ uid = strtol(label, &endptr, 10);
+ if (endptr == NULL || *endptr != ':')
+ return -1;
+
+ gid = strtol(endptr + 1, &endptr, 10);
+ if (endptr == NULL || *endptr != '\0')
+ return -1;
+
+ if (uidPtr)
+ *uidPtr = uid;
+ if (gidPtr)
+ *gidPtr = gid;
+ return 0;
+}
+
+static
+int virSecurityDACParseIds(virDomainDefPtr def, uid_t *uidPtr, gid_t *gidPtr)
+{
+ uid_t uid;
+ gid_t gid;
+ virSecurityLabelDefPtr seclabel;
+
+ if (def == NULL)
+ return -1;
+
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+ if (seclabel == NULL) {
+ virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+ _("security label for DAC not found"));
+ return -1;
+ }
+
+ if (seclabel->label && parseIds(seclabel->label, &uid, &gid))
{
+ virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+ _("failed to parse uid and gid for DAC "
+ "securit driver"));
+ return -1;
+ }
+
+ if (uidPtr)
+ *uidPtr = uid;
+ if (gidPtr)
+ *gidPtr = gid;
+
+ return 0;
+}
+
+static
+int virSecurityDACGetIds(virDomainDefPtr def, virSecurityDACDataPtr priv,
+ uid_t *uidPtr, gid_t *gidPtr)
+{
+ if (virSecurityDACParseIds(def, uidPtr, gidPtr) == 0)
+ return 0;
+
+ if (priv) {
+ if (uidPtr)
+ *uidPtr = priv->user;
+ if (gidPtr)
+ *gidPtr = priv->group;
+ return 0;
+ }
+ return -1;
+}
+
+static
+int virSecurityDACParseImageIds(virDomainDefPtr def,
+ uid_t *uidPtr, gid_t *gidPtr)
+{
+ uid_t uid;
+ gid_t gid;
+ virSecurityLabelDefPtr seclabel;
+
+ if (def == NULL)
+ return -1;
+
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+ if (seclabel == NULL) {
+ virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+ _("security label for DAC not found"));
+ return -1;
+ }
+
+ if (seclabel->imagelabel
+ && parseIds(seclabel->imagelabel, &uid, &gid)) {
+ virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+ _("failed to parse uid and gid for DAC "
+ "securit driver"));
+ return -1;
+ }
+
+ if (uidPtr)
+ *uidPtr = uid;
+ if (gidPtr)
+ *gidPtr = gid;
+
+ return 0;
+}
+
+static
+int virSecurityDACGetImageIds(virDomainDefPtr def, virSecurityDACDataPtr priv,
+ uid_t *uidPtr, gid_t *gidPtr)
+{
+ if (virSecurityDACParseImageIds(def, uidPtr, gidPtr) == 0)
+ return 0;
+
+ if (priv) {
+ if (uidPtr)
+ *uidPtr = priv->user;
+ if (gidPtr)
+ *gidPtr = priv->group;
+ return 0;
+ }
+ return -1;
+}
+
+
static virSecurityDriverStatus
virSecurityDACProbe(const char *virtDriver ATTRIBUTE_UNUSED)
{
@@ -85,7 +212,7 @@ virSecurityDACClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
static const char * virSecurityDACGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
{
- return "dac";
+ return SECURITY_DAC_NAME;
}
static const char * virSecurityDACGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
@@ -167,10 +294,17 @@ virSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk
ATTRIBUTE_UNUSED,
size_t depth ATTRIBUTE_UNUSED,
void *opaque)
{
- virSecurityManagerPtr mgr = opaque;
+ void **params = opaque;
+ virSecurityManagerPtr mgr = params[0];
+ virDomainDefPtr def = params[1];
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ uid_t user;
+ gid_t group;
- return virSecurityDACSetOwnership(path, priv->user, priv->group);
+ if (virSecurityDACGetImageIds(def, priv, &user, &group))
+ return -1;
+
+ return virSecurityDACSetOwnership(path, user, group);
}
@@ -180,6 +314,9 @@ virSecurityDACSetSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainDiskDefPtr disk)
{
+ uid_t user;
+ gid_t group;
+ void *params[2];
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
if (!priv->dynamicOwnership)
@@ -188,12 +325,17 @@ virSecurityDACSetSecurityImageLabel(virSecurityManagerPtr mgr,
if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
return 0;
+ if (virSecurityDACGetImageIds(def, priv, &user, &group))
+ return -1;
+
+ params[0] = mgr;
+ params[1] = def;
return virDomainDiskDefForeachPath(disk,
virSecurityManagerGetAllowDiskFormatProbing(mgr),
false,
- priv->user, priv->group,
+ user, group,
virSecurityDACSetSecurityFileLabel,
- mgr);
+ params);
}
@@ -259,10 +401,17 @@ virSecurityDACSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
const char *file,
void *opaque)
{
- virSecurityManagerPtr mgr = opaque;
+ void **params = opaque;
+ virSecurityManagerPtr mgr = params[0];
+ virDomainDefPtr def = params[1];
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ uid_t user;
+ gid_t group;
+
+ if (virSecurityDACGetIds(def, priv, &user, &group))
+ return -1;
- return virSecurityDACSetOwnership(file, priv->user, priv->group);
+ return virSecurityDACSetOwnership(file, user, group);
}
@@ -271,18 +420,26 @@ virSecurityDACSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
const char *file,
void *opaque)
{
- virSecurityManagerPtr mgr = opaque;
+ void **params = opaque;
+ virSecurityManagerPtr mgr = params[0];
+ virDomainDefPtr def = params[1];
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ uid_t user;
+ gid_t group;
- return virSecurityDACSetOwnership(file, priv->user, priv->group);
+ if (virSecurityDACGetIds(def, priv, &user, &group))
+ return -1;
+
+ return virSecurityDACSetOwnership(file, user, group);
}
static int
virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
- virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainDefPtr def,
virDomainHostdevDefPtr dev)
{
+ void *params[] = {mgr, def};
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
int ret = -1;
@@ -300,7 +457,8 @@ virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
if (!usb)
goto done;
- ret = usbDeviceFileIterate(usb, virSecurityDACSetSecurityUSBLabel, mgr);
+ ret = usbDeviceFileIterate(usb, virSecurityDACSetSecurityUSBLabel,
+ params);
usbFreeDevice(usb);
break;
}
@@ -314,7 +472,8 @@ virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
if (!pci)
goto done;
- ret = pciDeviceFileIterate(pci, virSecurityDACSetSecurityPCILabel, mgr);
+ ret = pciDeviceFileIterate(pci, virSecurityDACSetSecurityPCILabel,
+ params);
pciFreeDevice(pci);
break;
@@ -404,17 +563,23 @@ done:
static int
virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
+ virDomainDefPtr def,
virDomainChrSourceDefPtr dev)
{
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
char *in = NULL, *out = NULL;
int ret = -1;
+ uid_t user;
+ gid_t group;
+
+ if (virSecurityDACGetIds(def, priv, &user, &group))
+ return -1;
switch (dev->type) {
case VIR_DOMAIN_CHR_TYPE_DEV:
case VIR_DOMAIN_CHR_TYPE_FILE:
- ret = virSecurityDACSetOwnership(dev->data.file.path, priv->user,
priv->group);
+ ret = virSecurityDACSetOwnership(dev->data.file.path, user, group);
break;
case VIR_DOMAIN_CHR_TYPE_PIPE:
@@ -424,12 +589,12 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
goto done;
}
if (virFileExists(in) && virFileExists(out)) {
- if ((virSecurityDACSetOwnership(in, priv->user, priv->group) < 0)
||
- (virSecurityDACSetOwnership(out, priv->user, priv->group) < 0))
{
+ if ((virSecurityDACSetOwnership(in, user, group) < 0) ||
+ (virSecurityDACSetOwnership(out, user, group) < 0)) {
goto done;
}
} else if (virSecurityDACSetOwnership(dev->data.file.path,
- priv->user, priv->group) < 0) {
+ user, group) < 0) {
goto done;
}
ret = 0;
@@ -554,7 +719,7 @@ virSecurityDACSetChardevCallback(virDomainDefPtr def
ATTRIBUTE_UNUSED,
{
virSecurityManagerPtr mgr = opaque;
- return virSecurityDACSetChardevLabel(mgr, &dev->source);
+ return virSecurityDACSetChardevLabel(mgr, def, &dev->source);
}
@@ -565,6 +730,8 @@ virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
{
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
int i;
+ uid_t user;
+ gid_t group;
if (!priv->dynamicOwnership)
return 0;
@@ -591,16 +758,15 @@ virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
mgr) < 0)
return -1;
+ if (virSecurityDACGetImageIds(def, priv, &user, &group))
+ return -1;
+
if (def->os.kernel &&
- virSecurityDACSetOwnership(def->os.kernel,
- priv->user,
- priv->group) < 0)
+ virSecurityDACSetOwnership(def->os.kernel, user, group) < 0)
return -1;
if (def->os.initrd &&
- virSecurityDACSetOwnership(def->os.initrd,
- priv->user,
- priv->group) < 0)
+ virSecurityDACSetOwnership(def->os.initrd, user, group) < 0)
return -1;
return 0;
@@ -609,12 +775,17 @@ virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
static int
virSecurityDACSetSavedStateLabel(virSecurityManagerPtr mgr,
- virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainDefPtr def,
const char *savefile)
{
+ uid_t user;
+ gid_t group;
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
- return virSecurityDACSetOwnership(savefile, priv->user, priv->group);
+ if (virSecurityDACGetImageIds(def, priv, &user, &group))
+ return -1;
+
+ return virSecurityDACSetOwnership(savefile, user, group);
}
@@ -636,12 +807,16 @@ static int
virSecurityDACSetProcessLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def ATTRIBUTE_UNUSED)
{
+ uid_t user;
+ gid_t group;
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
- VIR_DEBUG("Dropping privileges of DEF to %u:%u",
- (unsigned int) priv->user, (unsigned int) priv->group);
+ if (virSecurityDACGetIds(def, priv, &user, &group))
+ return -1;
+
+ VIR_DEBUG("Dropping privileges of DEF to %u:%u", user, group);
- if (virSetUIDGID(priv->user, priv->group) < 0)
+ if (virSetUIDGID(user, group) < 0)
return -1;
return 0;
@@ -656,9 +831,83 @@ virSecurityDACVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
}
static int
-virSecurityDACGenLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
- virDomainDefPtr def ATTRIBUTE_UNUSED)
+virSecurityDACGenLabel(virSecurityManagerPtr mgr,
+ virDomainDefPtr def)
{
+ int rc = -1;
+ virSecurityLabelDefPtr seclabel;
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ if (mgr == NULL) {
+ virSecurityReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("invalid security driver"));
+ return rc;
+ }
+
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+ if (seclabel == NULL) {
+ return rc;
+ }
+
+ if (seclabel->imagelabel) {
+ virSecurityReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("security image label already "
+ "defined for VM"));
+ return rc;
+ }
+
+ if (seclabel->model
+ && STRNEQ(seclabel->model, SECURITY_DAC_NAME)) {
+ virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+ _("security label model %s is not supported "
+ "with selinux"),
+ seclabel->model);
+ return rc;
+ }
+
+ switch(seclabel->type) {
+ case VIR_DOMAIN_SECLABEL_STATIC:
+ if (seclabel->label == NULL) {
+ virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+ _("missing label for static security "
+ "driver"));
+ return rc;
+ }
+ break;
+ case VIR_DOMAIN_SECLABEL_DYNAMIC:
+ if (asprintf(&seclabel->label, "%d:%d", priv->user,
priv->group) < 0) {
+ virReportOOMError();
+ return rc;
+ }
+ if (seclabel->label == NULL) {
+ virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot generate dac user and group
id"));
+ return rc;
+ }
+ break;
+ case VIR_DOMAIN_SECLABEL_NONE:
+ /* no op */
+ break;
+ default:
+ virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected security label type
'%s'"),
+ virDomainSeclabelTypeToString(seclabel->type));
+ return rc;
+ }
+
+ if (!seclabel->norelabel) {
+ if (seclabel->imagelabel == NULL) {
+ seclabel->imagelabel = strdup(seclabel->label);
+ if (seclabel->imagelabel == NULL) {
+ virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot generate dac user and group
id"));
+ VIR_FREE(seclabel->label);
+ seclabel->label = NULL;
+ return rc;
+ }
+ }
+ }
+
return 0;
}
@@ -683,6 +932,15 @@ virSecurityDACGetProcessLabel(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
pid_t pid ATTRIBUTE_UNUSED,
virSecurityLabelPtr seclabel ATTRIBUTE_UNUSED)
{
+ virSecurityLabelDefPtr secdef =
+ virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+
+ if (!secdef || !seclabel)
+ return -1;
+
+ if (secdef->label)
+ strcpy(seclabel->label, secdef->label);
+
return 0;
}
@@ -724,7 +982,7 @@ static char *virSecurityDACGetMountOptions(virSecurityManagerPtr mgr
ATTRIBUTE_U
virSecurityDriver virSecurityDriverDAC = {
sizeof(virSecurityDACData),
- "virDAC",
+ SECURITY_DAC_NAME,
virSecurityDACProbe,
virSecurityDACOpen,
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
index 8ec4d3e..a9ca824 100644
--- a/src/security/security_manager.c
+++ b/src/security/security_manager.c
@@ -68,8 +68,7 @@ static virSecurityManagerPtr
virSecurityManagerNewDriver(virSecurityDriverPtr dr
return mgr;
}
-virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
- virSecurityManagerPtr secondary)
+virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary)
{
virSecurityManagerPtr mgr =
virSecurityManagerNewDriver(&virSecurityDriverStack,
@@ -81,12 +80,19 @@ virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr
primary,
if (!mgr)
return NULL;
- virSecurityStackSetPrimary(mgr, primary);
- virSecurityStackSetSecondary(mgr, secondary);
+ virSecurityStackAddPrimary(mgr, primary);
return mgr;
}
+int virSecurityManagerStackAddNested(virSecurityManagerPtr stack,
+ virSecurityManagerPtr nested)
+{
+ if (!STREQ("stack", stack->drv->name))
+ return -1;
+ return virSecurityStackAddNested(stack, nested);
+}
+
virSecurityManagerPtr virSecurityManagerNewDAC(const char *virtDriver,
uid_t user,
gid_t group,
@@ -308,25 +314,51 @@ int virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr
mgr,
int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm)
{
- if (vm->seclabel.type == VIR_DOMAIN_SECLABEL_DEFAULT) {
- if (mgr->defaultConfined)
- vm->seclabel.type = VIR_DOMAIN_SECLABEL_DYNAMIC;
- else
- vm->seclabel.type = VIR_DOMAIN_SECLABEL_NONE;
- }
+ int rc = 0;
+ size_t i;
+ virSecurityManagerPtr* sec_managers = NULL;
+ virSecurityLabelDefPtr seclabel;
- if ((vm->seclabel.type == VIR_DOMAIN_SECLABEL_NONE) &&
- mgr->requireConfined) {
- virSecurityReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Unconfined guests are not allowed on this
host"));
+ if (mgr == NULL || mgr->drv == NULL)
return -1;
- }
- if (mgr->drv->domainGenSecurityLabel)
- return mgr->drv->domainGenSecurityLabel(mgr, vm);
+ if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL)
+ return -1;
- virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return -1;
+ for (i = 0; sec_managers[i]; i++) {
+ seclabel = virDomainDefGetSecurityLabelDef(vm,
+ sec_managers[i]->drv->name);
+ if (seclabel == NULL) {
+ rc = -1;
+ goto cleanup;
+ }
+
+ if (seclabel->type == VIR_DOMAIN_SECLABEL_DEFAULT) {
+ if (sec_managers[i]->defaultConfined)
+ seclabel->type = VIR_DOMAIN_SECLABEL_DYNAMIC;
+ else
+ seclabel->type = VIR_DOMAIN_SECLABEL_NONE;
+ }
+
+ if ((seclabel->type == VIR_DOMAIN_SECLABEL_NONE) &&
+ sec_managers[i]->requireConfined) {
+ virSecurityReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Unconfined guests are not allowed on this
host"));
+ return -1;
+ }
+
+ if (!sec_managers[i]->drv->domainGenSecurityLabel) {
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ } else {
+ rc += sec_managers[i]->drv->domainGenSecurityLabel(sec_managers[i],
vm);
+ if (rc)
+ goto cleanup;
+ }
+ }
+
+cleanup:
+ VIR_FREE(sec_managers);
+ return rc;
}
int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
@@ -397,12 +429,17 @@ int virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
int virSecurityManagerVerify(virSecurityManagerPtr mgr,
virDomainDefPtr def)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
+
+ if (mgr == NULL || mgr->drv == NULL)
+ return 0;
+
/* NULL model == dynamic labelling, with whatever driver
* is active, so we can short circuit verify check to
* avoid drivers de-referencing NULLs by accident
*/
- if (!secdef->model)
+ secdef = virDomainDefGetSecurityLabelDef(def, mgr->drv->name);
+ if (secdef == NULL || secdef->model == NULL)
return 0;
if (mgr->drv->domainSecurityVerify)
@@ -435,3 +472,23 @@ char *virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
*/
return NULL;
}
+
+virSecurityManagerPtr*
+virSecurityManagerGetNested(virSecurityManagerPtr mgr)
+{
+ virSecurityManagerPtr* list = NULL;
+
+ if (STREQ("stack", mgr->drv->name)) {
+ return virSecurityStackGetNested(mgr);
+ }
+
+ if (VIR_ALLOC_N(list, 2) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ list[0] = mgr;
+ list[1] = NULL;
+ return list;
+}
+
diff --git a/src/security/security_manager.h b/src/security/security_manager.h
index f0bf60d..f86b84d 100644
--- a/src/security/security_manager.h
+++ b/src/security/security_manager.h
@@ -37,8 +37,9 @@ virSecurityManagerPtr virSecurityManagerNew(const char *name,
bool defaultConfined,
bool requireConfined);
-virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
- virSecurityManagerPtr secondary);
+virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary);
+int virSecurityManagerStackAddNested(virSecurityManagerPtr stack,
+ virSecurityManagerPtr nested);
virSecurityManagerPtr virSecurityManagerNewDAC(const char *virtDriver,
uid_t user,
@@ -109,4 +110,7 @@ int virSecurityManagerSetImageFDLabel(virSecurityManagerPtr mgr,
int fd);
char *virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
virDomainDefPtr vm);
+virSecurityManagerPtr*
+virSecurityManagerGetNested(virSecurityManagerPtr mgr);
+
#endif /* VIR_SECURITY_MANAGER_H__ */
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 2b8ff19..fe318be 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -271,46 +271,52 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
int c2 = 0;
context_t ctx = NULL;
const char *range;
- virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
+ virSecurityLabelDefPtr seclabel;
+ virSecuritySELinuxDataPtr data;
- VIR_DEBUG("SELinuxGenSecurityLabel %s", virSecurityManagerGetDriver(mgr));
- if ((def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) &&
- !def->seclabel.baselabel &&
- def->seclabel.model) {
+ if (mgr == NULL) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("security model already defined for
VM"));
+ "%s", _("invalid security driver"));
+ return rc;
+ }
+
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (seclabel == NULL) {
return rc;
}
- if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
- def->seclabel.label) {
+ data = virSecurityManagerGetPrivateData(mgr);
+
+ VIR_DEBUG("SELinuxGenSecurityLabel %s", virSecurityManagerGetDriver(mgr));
+ if (seclabel->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
+ seclabel->label) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("security label already defined for
VM"));
return rc;
}
- if (def->seclabel.imagelabel) {
+ if (seclabel->imagelabel) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("security image label already
defined for VM"));
return rc;
}
- if (def->seclabel.model &&
- STRNEQ(def->seclabel.model, SECURITY_SELINUX_NAME)) {
+ if (seclabel->model &&
+ STRNEQ(seclabel->model, SECURITY_SELINUX_NAME)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label model %s is not supported with
selinux"),
- def->seclabel.model);
+ seclabel->model);
return rc;
}
- VIR_DEBUG("SELinuxGenSecurityLabel %d", def->seclabel.type);
+ VIR_DEBUG("SELinuxGenSecurityLabel %d", seclabel->type);
- switch (def->seclabel.type) {
+ switch (seclabel->type) {
case VIR_DOMAIN_SECLABEL_STATIC:
- if (!(ctx = context_new(def->seclabel.label)) ) {
+ if (!(ctx = context_new(seclabel->label)) ) {
virReportSystemError(errno,
_("unable to allocate socket security context
'%s'"),
- def->seclabel.label);
+ seclabel->label);
return rc;
}
@@ -345,11 +351,11 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
}
} while (mcsAdd(mcs) == -1);
- def->seclabel.label =
- SELinuxGenNewContext(def->seclabel.baselabel ?
- def->seclabel.baselabel :
+ seclabel->label =
+ SELinuxGenNewContext(seclabel->baselabel ?
+ seclabel->baselabel :
data->domain_context, mcs);
- if (! def->seclabel.label) {
+ if (! seclabel->label) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot generate selinux context for %s"),
mcs);
goto cleanup;
@@ -363,21 +369,21 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
default:
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected security label type
'%s'"),
- virDomainSeclabelTypeToString(def->seclabel.type));
+ virDomainSeclabelTypeToString(seclabel->type));
goto cleanup;
}
- if (!def->seclabel.norelabel) {
- def->seclabel.imagelabel = SELinuxGenNewContext(data->file_context, mcs);
- if (!def->seclabel.imagelabel) {
+ if (!seclabel->norelabel) {
+ seclabel->imagelabel = SELinuxGenNewContext(data->domain_context, mcs);
+ if (!seclabel->imagelabel) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot generate selinux context for %s"),
mcs);
goto cleanup;
}
}
- if (!def->seclabel.model &&
- !(def->seclabel.model = strdup(SECURITY_SELINUX_NAME))) {
+ if (!seclabel->model &&
+ !(seclabel->model = strdup(SECURITY_SELINUX_NAME))) {
virReportOOMError();
goto cleanup;
}
@@ -386,12 +392,12 @@ SELinuxGenSecurityLabel(virSecurityManagerPtr mgr,
cleanup:
if (rc != 0) {
- if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC)
- VIR_FREE(def->seclabel.label);
- VIR_FREE(def->seclabel.imagelabel);
- if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
- !def->seclabel.baselabel)
- VIR_FREE(def->seclabel.model);
+ if (seclabel->type == VIR_DOMAIN_SECLABEL_DYNAMIC)
+ VIR_FREE(seclabel->label);
+ VIR_FREE(seclabel->imagelabel);
+ if (seclabel->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
+ !seclabel->baselabel)
+ VIR_FREE(seclabel->model);
}
if (ctx)
@@ -400,10 +406,10 @@ cleanup:
VIR_FREE(mcs);
VIR_DEBUG("model=%s label=%s imagelabel=%s baselabel=%s",
- NULLSTR(def->seclabel.model),
- NULLSTR(def->seclabel.label),
- NULLSTR(def->seclabel.imagelabel),
- NULLSTR(def->seclabel.baselabel));
+ NULLSTR(seclabel->model),
+ NULLSTR(seclabel->label),
+ NULLSTR(seclabel->imagelabel),
+ NULLSTR(seclabel->baselabel));
return rc;
}
@@ -416,8 +422,14 @@ SELinuxReserveSecurityLabel(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
security_context_t pctx;
context_t ctx = NULL;
const char *mcs;
+ virSecurityLabelDefPtr seclabel;
+
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (seclabel == NULL) {
+ return -1;
+ }
- if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
+ if (seclabel->type == VIR_DOMAIN_SECLABEL_STATIC)
return 0;
if (getpidcon(pid, &pctx) == -1) {
@@ -709,9 +721,16 @@ SELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
virDomainDiskDefPtr disk,
int migrated)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr seclabel;
+ virSecurityDeviceLabelDefPtr disk_seclabel;
- if (secdef->norelabel || (disk->seclabel &&
disk->seclabel->norelabel))
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (seclabel == NULL)
+ return -1;
+
+ disk_seclabel = virDomainDiskDefGetSecurityLabelDef(disk,
+ SECURITY_SELINUX_NAME);
+ if (seclabel->norelabel || (disk_seclabel &&
disk_seclabel->norelabel))
return 0;
/* Don't restore labels on readoly/shared disks, because
@@ -763,17 +782,21 @@ SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
size_t depth,
void *opaque)
{
+ int ret;
+ virSecurityDeviceLabelDefPtr disk_seclabel;
virSecuritySELinuxCallbackDataPtr cbdata = opaque;
const virSecurityLabelDefPtr secdef = cbdata->secdef;
- int ret;
virSecuritySELinuxDataPtr data =
virSecurityManagerGetPrivateData(cbdata->manager);
- if (disk->seclabel && disk->seclabel->norelabel)
+ disk_seclabel = virDomainDiskDefGetSecurityLabelDef(disk,
+ SECURITY_SELINUX_NAME);
+
+ if (disk_seclabel && disk_seclabel->norelabel)
return 0;
- if (disk->seclabel && !disk->seclabel->norelabel &&
- disk->seclabel->label) {
- ret = SELinuxSetFilecon(path, disk->seclabel->label);
+ if (disk_seclabel && !disk_seclabel->norelabel &&
+ disk_seclabel->label) {
+ ret = SELinuxSetFilecon(path, disk_seclabel->label);
} else if (depth == 0) {
if (disk->shared) {
@@ -788,14 +811,14 @@ SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
} else {
ret = SELinuxSetFileconOptional(path, data->content_context);
}
- if (ret == 1 && !disk->seclabel) {
+ if (ret == 1 && !disk_seclabel) {
/* If we failed to set a label, but virt_use_nfs let us
* proceed anyway, then we don't need to relabel later. */
- if (VIR_ALLOC(disk->seclabel) < 0) {
+ if (VIR_ALLOC(disk_seclabel) < 0) {
virReportOOMError();
return -1;
}
- disk->seclabel->norelabel = true;
+ disk_seclabel->norelabel = true;
ret = 0;
}
return ret;
@@ -807,11 +830,15 @@ SELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainDiskDefPtr disk)
{
+ bool allowDiskFormatProbing;
virSecuritySELinuxCallbackData cbdata;
- cbdata.secdef = &def->seclabel;
cbdata.manager = mgr;
+ cbdata.secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
- bool allowDiskFormatProbing = virSecurityManagerGetAllowDiskFormatProbing(mgr);
+ allowDiskFormatProbing = virSecurityManagerGetAllowDiskFormatProbing(mgr);
+
+ if (cbdata.secdef == NULL)
+ return -1;
if (cbdata.secdef->norelabel)
return 0;
@@ -838,9 +865,12 @@ static int
SELinuxSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
const char *file, void *opaque)
{
+ virSecurityLabelDefPtr secdef;
virDomainDefPtr def = opaque;
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
return SELinuxSetFilecon(file, secdef->imagelabel);
}
@@ -848,8 +878,12 @@ static int
SELinuxSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
const char *file, void *opaque)
{
+ virSecurityLabelDefPtr secdef;
virDomainDefPtr def = opaque;
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
return SELinuxSetFilecon(file, secdef->imagelabel);
}
@@ -860,9 +894,13 @@ SELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
virDomainHostdevDefPtr dev)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
int ret = -1;
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
+
if (secdef->norelabel)
return 0;
@@ -929,9 +967,13 @@ SELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
virDomainHostdevDefPtr dev)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
int ret = -1;
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
+
if (secdef->norelabel)
return 0;
@@ -982,10 +1024,14 @@ SELinuxSetSecurityChardevLabel(virDomainDefPtr def,
virDomainChrSourceDefPtr dev)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
char *in = NULL, *out = NULL;
int ret = -1;
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
+
if (secdef->norelabel)
return 0;
@@ -1028,10 +1074,14 @@ SELinuxRestoreSecurityChardevLabel(virDomainDefPtr def,
virDomainChrSourceDefPtr dev)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
char *in = NULL, *out = NULL;
int ret = -1;
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
+
if (secdef->norelabel)
return 0;
@@ -1121,12 +1171,16 @@ SELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
virDomainDefPtr def,
int migrated ATTRIBUTE_UNUSED)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
int i;
int rc = 0;
VIR_DEBUG("Restoring security label on %s", def->name);
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
+
if (secdef->norelabel)
return 0;
@@ -1171,7 +1225,11 @@ static int
SELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainDefPtr def)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
if (secdef->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
if (secdef->label != NULL) {
@@ -1196,7 +1254,11 @@ SELinuxSetSavedStateLabel(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
virDomainDefPtr def,
const char *savefile)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
if (secdef->norelabel)
return 0;
@@ -1210,7 +1272,11 @@ SELinuxRestoreSavedStateLabel(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
virDomainDefPtr def,
const char *savefile)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
if (secdef->norelabel)
return 0;
@@ -1223,7 +1289,12 @@ static int
SELinuxSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainDefPtr def)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
+
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
@@ -1248,12 +1319,16 @@ SELinuxSetSecurityProcessLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def)
{
/* TODO: verify DOI */
- const virSecurityLabelDefPtr secdef = &def->seclabel;
- VIR_DEBUG("SELinuxSetSecurityProcessLabel %s", secdef->label);
+ virSecurityLabelDefPtr secdef;
- if (def->seclabel.label == NULL)
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
+
+ if (secdef->label == NULL)
return 0;
+ VIR_DEBUG("SELinuxSetSecurityProcessLabel %s", secdef->label);
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
@@ -1280,13 +1355,17 @@ SELinuxSetSecurityDaemonSocketLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def)
{
/* TODO: verify DOI */
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
context_t execcon = NULL;
context_t proccon = NULL;
security_context_t scon = NULL;
int rc = -1;
- if (def->seclabel.label == NULL)
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
+
+ if (secdef->label == NULL)
return 0;
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
@@ -1350,9 +1429,13 @@ static int
SELinuxSetSecuritySocketLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm)
{
- const virSecurityLabelDefPtr secdef = &vm->seclabel;
+ virSecurityLabelDefPtr secdef;
int rc = -1;
+ secdef = virDomainDefGetSecurityLabelDef(vm, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
+
if (secdef->label == NULL)
return 0;
@@ -1388,9 +1471,13 @@ SELinuxClearSecuritySocketLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def)
{
/* TODO: verify DOI */
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
- if (def->seclabel.label == NULL)
+ if (secdef->label == NULL)
return 0;
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
@@ -1466,9 +1553,13 @@ SELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def,
const char *stdin_path)
{
- virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
- const virSecurityLabelDefPtr secdef = &def->seclabel;
int i;
+ virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
if (secdef->norelabel)
return 0;
@@ -1528,7 +1619,11 @@ SELinuxSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainDefPtr def,
int fd)
{
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
if (secdef->imagelabel == NULL)
return 0;
@@ -1538,13 +1633,17 @@ SELinuxSetImageFDLabel(virSecurityManagerPtr mgr
ATTRIBUTE_UNUSED,
static char *genImageLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def) {
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
const char *range;
context_t ctx = NULL;
char *label = NULL;
const char *mcs = NULL;
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ goto cleanup;
+
if (secdef->label) {
ctx = context_new(secdef->label);
if (!ctx) {
@@ -1575,7 +1674,11 @@ cleanup:
static char *SELinuxGetSecurityMountOptions(virSecurityManagerPtr mgr,
virDomainDefPtr def) {
char *opts = NULL;
- const virSecurityLabelDefPtr secdef = &def->seclabel;
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return NULL;
if (! secdef->imagelabel)
secdef->imagelabel = genImageLabel(mgr,def);
diff --git a/src/security/security_stack.c b/src/security/security_stack.c
index 6ecd099..dd0aebc 100644
--- a/src/security/security_stack.c
+++ b/src/security/security_stack.c
@@ -23,29 +23,70 @@
#include "security_stack.h"
#include "virterror_internal.h"
+#include "memory.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
typedef struct _virSecurityStackData virSecurityStackData;
typedef virSecurityStackData *virSecurityStackDataPtr;
+typedef struct _virSecurityStackItem virSecurityStackItem;
+typedef virSecurityStackItem* virSecurityStackItemPtr;
+
+struct _virSecurityStackItem {
+ virSecurityManagerPtr securityManager;
+ virSecurityStackItemPtr next;
+};
struct _virSecurityStackData {
virSecurityManagerPtr primary;
- virSecurityManagerPtr secondary;
+ virSecurityStackItemPtr itemsHead;
};
-void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
- virSecurityManagerPtr primary)
+int
+virSecurityStackAddPrimary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr primary)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ if (virSecurityStackAddNested(mgr, primary) < 0)
+ return -1;
priv->primary = primary;
+ return 0;
+}
+
+int
+virSecurityStackAddNested(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr nested)
+{
+ virSecurityStackItemPtr item = NULL;
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ if (VIR_ALLOC(item) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+ item->securityManager = nested;
+ item->next = priv->itemsHead;
+ priv->itemsHead = item;
+ return 0;
+}
+
+virSecurityManagerPtr
+virSecurityStackGetPrimary(virSecurityManagerPtr mgr)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ return (priv->primary) ? priv->primary :
priv->itemsHead->securityManager;
+}
+
+void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr primary)
+{
+ virSecurityStackAddPrimary(mgr, primary);
}
void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
virSecurityManagerPtr secondary)
{
- virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
- priv->secondary = secondary;
+ virSecurityStackAddNested(mgr, secondary);
}
static virSecurityDriverStatus
@@ -64,9 +105,14 @@ static int
virSecurityStackClose(virSecurityManagerPtr mgr)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr next, item = priv->itemsHead;
- virSecurityManagerFree(priv->primary);
- virSecurityManagerFree(priv->secondary);
+ while (item) {
+ next = item->next;
+ virSecurityManagerFree(item->securityManager);
+ VIR_FREE(item);
+ item = next;
+ }
return 0;
}
@@ -74,17 +120,13 @@ virSecurityStackClose(virSecurityManagerPtr mgr)
static const char *
virSecurityStackGetModel(virSecurityManagerPtr mgr)
{
- virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
-
- return virSecurityManagerGetModel(priv->primary);
+ return virSecurityManagerGetModel(virSecurityStackGetPrimary(mgr));
}
static const char *
virSecurityStackGetDOI(virSecurityManagerPtr mgr)
{
- virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
-
- return virSecurityManagerGetDOI(priv->primary);
+ return virSecurityManagerGetDOI(virSecurityStackGetPrimary(mgr));
}
static int
@@ -92,13 +134,13 @@ virSecurityStackVerify(virSecurityManagerPtr mgr,
virDomainDefPtr def)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
- if (virSecurityManagerVerify(priv->primary, def) < 0)
- rc = -1;
-
- if (virSecurityManagerVerify(priv->secondary, def) < 0)
- rc = -1;
+ for(; item; item = item->next) {
+ if (virSecurityManagerVerify(item->securityManager, def) < 0)
+ rc = -1;
+ }
return rc;
}
@@ -108,12 +150,12 @@ static int
virSecurityStackGenLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm)
{
- virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
int rc = 0;
- if (virSecurityManagerGenLabel(priv->primary, vm) < 0)
+ if (virSecurityManagerGenLabel(virSecurityStackGetPrimary(mgr), vm) < 0)
rc = -1;
+// TODO
#if 0
/* We don't allow secondary drivers to generate labels.
* This may have to change in the future, but requires
@@ -133,11 +175,12 @@ static int
virSecurityStackReleaseLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm)
{
- virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
int rc = 0;
- if (virSecurityManagerReleaseLabel(priv->primary, vm) < 0)
+ if (virSecurityManagerReleaseLabel(virSecurityStackGetPrimary(mgr), vm) < 0)
rc = -1;
+
+// TODO
#if 0
/* XXX See note in GenLabel */
if (virSecurityManagerReleaseLabel(priv->secondary, vm) < 0)
@@ -153,11 +196,11 @@ virSecurityStackReserveLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm,
pid_t pid)
{
- virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
int rc = 0;
- if (virSecurityManagerReserveLabel(priv->primary, vm, pid) < 0)
+ if (virSecurityManagerReserveLabel(virSecurityStackGetPrimary(mgr), vm, pid) < 0)
rc = -1;
+// TODO
#if 0
/* XXX See note in GenLabel */
if (virSecurityManagerReserveLabel(priv->secondary, vm, pid) < 0)
@@ -174,12 +217,13 @@ virSecurityStackSetSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainDiskDefPtr disk)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
- if (virSecurityManagerSetImageLabel(priv->secondary, vm, disk) < 0)
- rc = -1;
- if (virSecurityManagerSetImageLabel(priv->primary, vm, disk) < 0)
- rc = -1;
+ for (; item; item = item->next) {
+ if (virSecurityManagerSetImageLabel(item->securityManager, vm, disk) < 0)
+ rc = -1;
+ }
return rc;
}
@@ -191,12 +235,13 @@ virSecurityStackRestoreSecurityImageLabel(virSecurityManagerPtr
mgr,
virDomainDiskDefPtr disk)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
- if (virSecurityManagerRestoreImageLabel(priv->secondary, vm, disk) < 0)
- rc = -1;
- if (virSecurityManagerRestoreImageLabel(priv->primary, vm, disk) < 0)
- rc = -1;
+ for (; item; item = item->next) {
+ if (virSecurityManagerRestoreImageLabel(item->securityManager, vm, disk) <
0)
+ rc = -1;
+ }
return rc;
}
@@ -209,12 +254,13 @@ virSecurityStackSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
- if (virSecurityManagerSetHostdevLabel(priv->secondary, vm, dev) < 0)
- rc = -1;
- if (virSecurityManagerSetHostdevLabel(priv->primary, vm, dev) < 0)
- rc = -1;
+ for (; item; item = item->next) {
+ if (virSecurityManagerSetHostdevLabel(item->securityManager, vm, dev) < 0)
+ rc = -1;
+ }
return rc;
}
@@ -226,12 +272,13 @@ virSecurityStackRestoreSecurityHostdevLabel(virSecurityManagerPtr
mgr,
virDomainHostdevDefPtr dev)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
- if (virSecurityManagerRestoreHostdevLabel(priv->secondary, vm, dev) < 0)
- rc = -1;
- if (virSecurityManagerRestoreHostdevLabel(priv->primary, vm, dev) < 0)
- rc = -1;
+ for (; item; item = item->next) {
+ if (virSecurityManagerRestoreHostdevLabel(item->securityManager, vm, dev) <
0)
+ rc = -1;
+ }
return rc;
}
@@ -243,12 +290,13 @@ virSecurityStackSetSecurityAllLabel(virSecurityManagerPtr mgr,
const char *stdin_path)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
- if (virSecurityManagerSetAllLabel(priv->secondary, vm, stdin_path) < 0)
- rc = -1;
- if (virSecurityManagerSetAllLabel(priv->primary, vm, stdin_path) < 0)
- rc = -1;
+ for (; item; item = item->next) {
+ if (virSecurityManagerSetAllLabel(item->securityManager, vm, stdin_path) <
0)
+ rc = -1;
+ }
return rc;
}
@@ -260,12 +308,13 @@ virSecurityStackRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
int migrated)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
- if (virSecurityManagerRestoreAllLabel(priv->secondary, vm, migrated) < 0)
- rc = -1;
- if (virSecurityManagerRestoreAllLabel(priv->primary, vm, migrated) < 0)
- rc = -1;
+ for (; item; item = item->next) {
+ if (virSecurityManagerRestoreAllLabel(item->securityManager, vm, migrated)
< 0)
+ rc = -1;
+ }
return rc;
}
@@ -277,12 +326,13 @@ virSecurityStackSetSavedStateLabel(virSecurityManagerPtr mgr,
const char *savefile)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
- if (virSecurityManagerSetSavedStateLabel(priv->secondary, vm, savefile) < 0)
- rc = -1;
- if (virSecurityManagerSetSavedStateLabel(priv->primary, vm, savefile) < 0)
- rc = -1;
+ for (; item; item = item->next) {
+ if (virSecurityManagerSetSavedStateLabel(item->securityManager, vm, savefile)
< 0)
+ rc = -1;
+ }
return rc;
}
@@ -294,12 +344,13 @@ virSecurityStackRestoreSavedStateLabel(virSecurityManagerPtr mgr,
const char *savefile)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
- if (virSecurityManagerRestoreSavedStateLabel(priv->secondary, vm, savefile) <
0)
- rc = -1;
- if (virSecurityManagerRestoreSavedStateLabel(priv->primary, vm, savefile) < 0)
- rc = -1;
+ for (; item; item = item->next) {
+ if (virSecurityManagerRestoreSavedStateLabel(item->securityManager, vm,
savefile) < 0)
+ rc = -1;
+ }
return rc;
}
@@ -310,12 +361,13 @@ virSecurityStackSetProcessLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
- if (virSecurityManagerSetProcessLabel(priv->secondary, vm) < 0)
- rc = -1;
- if (virSecurityManagerSetProcessLabel(priv->primary, vm) < 0)
- rc = -1;
+ for (; item; item = item->next) {
+ if (virSecurityManagerSetProcessLabel(item->securityManager, vm) < 0)
+ rc = -1;
+ }
return rc;
}
@@ -326,14 +378,14 @@ virSecurityStackGetProcessLabel(virSecurityManagerPtr mgr,
pid_t pid,
virSecurityLabelPtr seclabel)
{
- virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
int rc = 0;
+// TODO
#if 0
if (virSecurityManagerGetProcessLabel(priv->secondary, vm, pid, seclabel) < 0)
rc = -1;
#endif
- if (virSecurityManagerGetProcessLabel(priv->primary, vm, pid, seclabel) < 0)
+ if (virSecurityManagerGetProcessLabel(virSecurityStackGetPrimary(mgr), vm, pid,
seclabel) < 0)
rc = -1;
return rc;
@@ -345,12 +397,13 @@ virSecurityStackSetDaemonSocketLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
- if (virSecurityManagerSetDaemonSocketLabel(priv->secondary, vm) < 0)
- rc = -1;
- if (virSecurityManagerSetDaemonSocketLabel(priv->primary, vm) < 0)
- rc = -1;
+ for (; item; item = item->next) {
+ if (virSecurityManagerSetDaemonSocketLabel(item->securityManager, vm) < 0)
+ rc = -1;
+ }
return rc;
}
@@ -361,12 +414,13 @@ virSecurityStackSetSocketLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
- if (virSecurityManagerSetSocketLabel(priv->secondary, vm) < 0)
- rc = -1;
- if (virSecurityManagerSetSocketLabel(priv->primary, vm) < 0)
- rc = -1;
+ for (; item; item = item->next) {
+ if (virSecurityManagerSetSocketLabel(item->securityManager, vm) < 0)
+ rc = -1;
+ }
return rc;
}
@@ -377,12 +431,13 @@ virSecurityStackClearSocketLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
- if (virSecurityManagerClearSocketLabel(priv->secondary, vm) < 0)
- rc = -1;
- if (virSecurityManagerClearSocketLabel(priv->primary, vm) < 0)
- rc = -1;
+ for (; item; item = item->next) {
+ if (virSecurityManagerClearSocketLabel(item->securityManager, vm) < 0)
+ rc = -1;
+ }
return rc;
}
@@ -393,12 +448,13 @@ virSecurityStackSetImageFDLabel(virSecurityManagerPtr mgr,
int fd)
{
virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item = priv->itemsHead;
int rc = 0;
- if (virSecurityManagerSetImageFDLabel(priv->secondary, vm, fd) < 0)
- rc = -1;
- if (virSecurityManagerSetImageFDLabel(priv->primary, vm, fd) < 0)
- rc = -1;
+ for (; item; item = item->next) {
+ if (virSecurityManagerSetImageFDLabel(item->securityManager, vm, fd) < 0)
+ rc = -1;
+ }
return rc;
}
@@ -408,6 +464,29 @@ static char *virSecurityStackGetMountOptions(virSecurityManagerPtr
mgr ATTRIBUTE
return NULL;
}
+virSecurityManagerPtr*
+virSecurityStackGetNested(virSecurityManagerPtr mgr)
+{
+ virSecurityManagerPtr *list = NULL;
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ virSecurityStackItemPtr item;
+ int len = 0, i = 0;
+
+ for (item = priv->itemsHead; item; item = item->next)
+ len++;
+
+ if (VIR_ALLOC_N(list, len + 1) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ for (item = priv->itemsHead; item; item = item->next, i++)
+ list[i] = item->securityManager;
+ list[len] = NULL;
+
+ return list;
+}
+
virSecurityDriver virSecurityDriverStack = {
sizeof(virSecurityStackData),
"stack",
diff --git a/src/security/security_stack.h b/src/security/security_stack.h
index bc83ff3..13a7a88 100644
--- a/src/security/security_stack.h
+++ b/src/security/security_stack.h
@@ -25,9 +25,22 @@
extern virSecurityDriver virSecurityDriverStack;
+
+int
+virSecurityStackAddPrimary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr primary);
+int
+virSecurityStackAddNested(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr nested);
+virSecurityManagerPtr
+virSecurityStackGetPrimary(virSecurityManagerPtr mgr);
+
void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
virSecurityManagerPtr primary);
void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
virSecurityManagerPtr secondary);
+virSecurityManagerPtr*
+virSecurityStackGetNested(virSecurityManagerPtr mgr);
+
#endif /* __VIR_SECURITY_DAC */
--
1.7.1