[libvirt] [PATCH 2/7] Update security drivers to handle multiple security labels in internal data structures
Michal Privoznik
mprivozn at redhat.com
Tue Jun 5 14:38:51 UTC 2012
On 21.05.2012 15:39, Marcelo Cerri wrote:
> ---
> 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(-)
>
Doesn't apply cleanly:
CONFLICT (content): Merge conflict in src/security/security_dac.c
However, this is caused by my earlier patch which converted security
driver struct initialization to follow C99 hence conflict can be
resolved easily.
> 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;
> +}
> +
Again, blank newline on the EOF.
> 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 */
More information about the libvir-list
mailing list