virSecurityManagerGenLabel;
virSecurityManagerGetDOI;
virSecurityManagerGetModel;
+virSecurityManagerGetNested;
virSecurityManagerGetProcessLabel;
virSecurityManagerNew;
virSecurityManagerNewStack;
virSecurityManagerSetProcessLabel;
virSecurityManagerSetSavedStateLabel;
virSecurityManagerSetSocketLabel;
+virSecurityManagerStackAddNested;
virSecurityManagerVerify;
virSecurityManagerGetMountOptions;
if (!dac)
goto error;
- if (!(driver->securityManager = virSecurityManagerNewStack(mgr,
- dac))) {
+ if (!(driver->securityManager = virSecurityManagerNewStack(mgr)) ||
+ !(virSecurityManagerStackAddNested(mgr, dac))) {
virSecurityManagerFree(dac);
goto error;
qemuCreateCapabilities(virCapsPtr oldcaps,
struct qemud_driver *driver)
{
+ size_t i;
virCapsPtr caps;
+ virSecurityManagerPtr *sec_managers = NULL;
+ /* Security driver data */
+ const char *doi, *model;
/* Basic host arch / guest machine capabilities */
if (!(caps = qemuCapsInit(oldcaps))) {
goto err_exit;
}
- /* Security driver data */
- const char *doi, *model;
+ /* access sec drivers and create a sec model for each one */
+ sec_managers = virSecurityManagerGetNested(driver->securityManager);
+ if (sec_managers == NULL) {
+ goto err_exit;
+ }
- doi = virSecurityManagerGetDOI(driver->securityManager);
- model = virSecurityManagerGetModel(driver->securityManager);
+ /* calculate length */
+ for (i = 0; sec_managers[i]; i++)
+ ;
+ caps->host.nsecModels = i;
- if (VIR_ALLOC(caps->host.secModels) < 0) {
+ if (VIR_ALLOC_N(caps->host.secModels, caps->host.nsecModels) < 0)
goto no_memory;
- }
- if (STRNEQ(model, "none")) {
- if (!(caps->host.secModels[0].model = strdup(model)))
+ for (i = 0; sec_managers[i]; i++) {
+ doi = virSecurityManagerGetDOI(sec_managers[i]);
+ model = virSecurityManagerGetModel(sec_managers[i]);
+ if (!(caps->host.secModels[i].model = strdup(model)))
goto no_memory;
- if (!(caps->host.secModels[0].doi = strdup(doi)))
+ if (!(caps->host.secModels[i].doi = strdup(doi)))
goto no_memory;
+ VIR_DEBUG("Initialized caps for security driver \"%s\" with "
+ "DOI \"%s\"", model, doi);
}
-
- VIR_DEBUG("Initialized caps for security driver \"%s\" with "
- "DOI \"%s\"", model, doi);
+ VIR_FREE(sec_managers);
return caps;
no_memory:
virReportOOMError();
err_exit:
+ VIR_FREE(sec_managers);
virCapabilitiesFree(caps);
return NULL;
}
qemuDriverLock(driver);
memset(secmodel, 0, sizeof(*secmodel));
- /* NULL indicates no driver, which we treat as
- * success, but simply return no data in *secmodel */
- if (driver->caps->host.secModels[0].model == NULL)
+ /* We treat no driver as success, but simply return no data in *secmodel */
+ if (driver->caps->host.nsecModels == 0 ||
+ driver->caps->host.secModels[0].model == NULL)
goto cleanup;
p = driver->caps->host.secModels[0].model;
virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
/* Clear out dynamically assigned labels */
- if (vm->def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
- if (!vm->def->seclabels[0]->baselabel)
- VIR_FREE(vm->def->seclabels[0]->model);
- VIR_FREE(vm->def->seclabels[0]->label);
+ for (i = 0; i < vm->def->nseclabels; i++) {
+ if (vm->def->seclabels[i]->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
+ VIR_FREE(vm->def->seclabels[i]->label);
+ }
+ VIR_FREE(vm->def->seclabels[i]->imagelabel);
}
- VIR_FREE(vm->def->seclabels[0]->imagelabel);
virDomainDefClearDeviceAliases(vm->def);
if (!priv->persistentAddrs) {
virDomainChrSourceDefPtr monConfig,
bool monJSON)
{
+ size_t i;
char ebuf[1024];
int logfile = -1;
char *timestamp;
bool running = true;
virDomainPausedReason reason;
virSecurityLabelPtr seclabel = NULL;
+ virSecurityLabelDefPtr seclabeldef = NULL;
+ virSecurityManagerPtr* sec_managers = NULL;
+ const char *model;
VIR_DEBUG("Beginning VM attach process");
goto no_memory;
VIR_DEBUG("Detect security driver config");
- vm->def->seclabels[0]->type = VIR_DOMAIN_SECLABEL_STATIC;
- if (VIR_ALLOC(seclabel) < 0)
- goto no_memory;
- if (virSecurityManagerGetProcessLabel(driver->securityManager,
- vm->def, vm->pid, seclabel) < 0)
+ sec_managers = virSecurityManagerGetNested(driver->securityManager);
+ if (sec_managers == NULL) {
goto cleanup;
- if (driver->caps->host.secModels[0].model &&
- !(vm->def->seclabels[0]->model = strdup(driver->caps->host.secModels[0].model)))
- goto no_memory;
- if (!(vm->def->seclabels[0]->label = strdup(seclabel->label)))
- goto no_memory;
+ }
+
+ for (i = 0; sec_managers[i]; i++) {
+ model = virSecurityManagerGetModel(sec_managers[i]);
+ seclabeldef = virDomainDefGetSecurityLabelDef(vm->def, model);
+ if (seclabeldef == NULL) {
+ goto cleanup;
+ }
+ seclabeldef->type = VIR_DOMAIN_SECLABEL_STATIC;
+ if (VIR_ALLOC(seclabel) < 0)
+ goto no_memory;
+ if (virSecurityManagerGetProcessLabel(driver->securityManager,
+ vm->def, vm->pid, seclabel) < 0)
+ goto cleanup;
+
+ if (!(seclabeldef->model = strdup(model)))
+ goto no_memory;
+
+ if (!(seclabeldef->label = strdup(seclabel->label)))
+ goto no_memory;
+ VIR_FREE(seclabel);
+ }
VIR_DEBUG("Creating domain log file");
if ((logfile = qemuDomainCreateLog(driver, vm, false)) < 0)
VIR_FORCE_CLOSE(logfile);
VIR_FREE(seclabel);
+ VIR_FREE(sec_managers);
return 0;
* pretend we never started it */
VIR_FORCE_CLOSE(logfile);
VIR_FREE(seclabel);
+ VIR_FREE(sec_managers);
virDomainChrSourceDefFree(monConfig);
return -1;
}
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;
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;
+ }
virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot update AppArmor profile "
- "\'%s\'"),
+ _("cannot update AppArmor profile \'%s\'"),
secdef->imagelabel);
return -1;
}
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;
+ }
virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot update AppArmor profile "
- "\'%s\'"),
+ _("cannot update AppArmor profile \'%s\'"),
secdef->imagelabel);
return -1;
}
{
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) {
virReportError(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)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s",
_("security label already defined for VM"));
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) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot load AppArmor profile "
- "\'%s\'"), def->seclabel.label);
+ "\'%s\'"), secdef->label);
goto err;
}
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);
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
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);
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) {
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;
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;
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) {
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;
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;
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;
#include "storage_file.h"
#define VIR_FROM_THIS VIR_FROM_SECURITY
+#define SECURITY_DAC_NAME "dac"
typedef struct _virSecurityDACData virSecurityDACData;
typedef virSecurityDACData *virSecurityDACDataPtr;
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;
+
+ if (virStrToLong_ui(label, &endptr, 10, &uid) ||
+ endptr == NULL || *endptr != ':') {
+ return -1;
+ }
+
+ if (virStrToLong_ui(endptr + 1, NULL, 10, &gid))
+ 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) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("security label for DAC not found in domain %s"),
+ def->name);
+ return -1;
+ }
+
+ if (seclabel->label && parseIds(seclabel->label, &uid, &gid)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("failed to parse uid and gid for DAC "
+ "security driver: %s"), seclabel->label);
+ 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) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("security label for DAC not found in domain %s"),
+ def->name);
+ return -1;
+ }
+
+ if (seclabel->imagelabel
+ && parseIds(seclabel->imagelabel, &uid, &gid)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("failed to parse uid and gid for DAC "
+ "security driver: %s"), seclabel->label);
+ 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)
{
static const char * virSecurityDACGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
{
- return "dac";
+ return SECURITY_DAC_NAME;
}
static const char * virSecurityDACGetDOI(virSecurityManagerPtr mgr 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;
+
+ if (virSecurityDACGetImageIds(def, priv, &user, &group))
+ return -1;
- return virSecurityDACSetOwnership(path, priv->user, priv->group);
+ return virSecurityDACSetOwnership(path, user, group);
}
virDomainDiskDefPtr disk)
{
+ uid_t user;
+ gid_t group;
+ void *params[2];
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
if (!priv->dynamicOwnership)
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);
}
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);
}
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;
if (!usb)
goto done;
- ret = usbDeviceFileIterate(usb, virSecurityDACSetSecurityUSBLabel, mgr);
+ ret = usbDeviceFileIterate(usb, virSecurityDACSetSecurityUSBLabel,
+ params);
usbFreeDevice(usb);
break;
}
if (!pci)
goto done;
- ret = pciDeviceFileIterate(pci, virSecurityDACSetSecurityPCILabel, mgr);
+ ret = pciDeviceFileIterate(pci, virSecurityDACSetSecurityPCILabel,
+ params);
pciFreeDevice(pci);
break;
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:
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;
{
virSecurityManagerPtr mgr = opaque;
- return virSecurityDACSetChardevLabel(mgr, &dev->source);
+ return virSecurityDACSetChardevLabel(mgr, def, &dev->source);
}
{
virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
int i;
+ uid_t user;
+ gid_t group;
if (!priv->dynamicOwnership)
return 0;
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;
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);
}
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;
}
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) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("invalid security driver"));
+ return rc;
+ }
+
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
+ if (seclabel == NULL) {
+ return rc;
+ }
+
+ if (seclabel->imagelabel) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("security image label already "
+ "defined for VM"));
+ return rc;
+ }
+
+ if (seclabel->model
+ && STRNEQ(seclabel->model, SECURITY_DAC_NAME)) {
+ virReportError(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) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("missing label for static security "
+ "driver in domain %s"), def->name);
+ return rc;
+ }
+ break;
+ case VIR_DOMAIN_SECLABEL_DYNAMIC:
+ if (virAsprintf(&seclabel->label, "%d:%d", priv->user, priv->group) < 0) {
+ virReportOOMError();
+ return rc;
+ }
+ if (seclabel->label == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot generate dac user and group id "
+ "for domain %s"), def->name);
+ return rc;
+ }
+ break;
+ case VIR_DOMAIN_SECLABEL_NONE:
+ /* no op */
+ break;
+ default:
+ virReportError(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) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot generate dac user and group id "
+ "for domain %s"), def->name);
+ VIR_FREE(seclabel->label);
+ seclabel->label = NULL;
+ return rc;
+ }
+ }
+ }
+
return 0;
}
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;
}
virSecurityDriver virSecurityDriverDAC = {
.privateDataLen = sizeof(virSecurityDACData),
- .name = "virDAC",
+ .name = SECURITY_DAC_NAME,
.probe = virSecurityDACProbe,
.open = virSecurityDACOpen,
.close = virSecurityDACClose,
return mgr;
}
-virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
- virSecurityManagerPtr secondary)
+virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary)
{
virSecurityManagerPtr mgr =
virSecurityManagerNewDriver(&virSecurityDriverStack,
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,
int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm)
{
- if (vm->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DEFAULT) {
- if (mgr->defaultConfined) {
- vm->seclabels[0]->type = VIR_DOMAIN_SECLABEL_DYNAMIC;
- } else {
- vm->seclabels[0]->type = VIR_DOMAIN_SECLABEL_NONE;
- vm->seclabels[0]->norelabel = true;
- }
- }
+ int rc = 0;
+ size_t i;
+ virSecurityManagerPtr* sec_managers = NULL;
+ virSecurityLabelDefPtr seclabel;
- if ((vm->seclabels[0]->type == VIR_DOMAIN_SECLABEL_NONE) &&
- mgr->requireConfined) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Unconfined guests are not allowed on this host"));
+ if (mgr == NULL || mgr->drv == NULL)
+ return -1;
+
+ if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL)
return -1;
- }
- if (mgr->drv->domainGenSecurityLabel)
- return mgr->drv->domainGenSecurityLabel(mgr, vm);
+ for (i = 0; sec_managers[i]; i++) {
+ seclabel = virDomainDefGetSecurityLabelDef(vm,
+ sec_managers[i]->drv->name);
+ if (seclabel == NULL) {
+ rc = -1;
+ goto cleanup;
+ }
- virReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return -1;
+ 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) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Unconfined guests are not allowed on this host"));
+ rc = -1;
+ goto cleanup;
+ }
+
+ if (!sec_managers[i]->drv->domainGenSecurityLabel) {
+ virReportError(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,
int virSecurityManagerVerify(virSecurityManagerPtr mgr,
virDomainDefPtr def)
{
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ 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)
*/
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;
+}
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,
int fd);
char *virSecurityManagerGetMountOptions(virSecurityManagerPtr mgr,
virDomainDefPtr vm);
+virSecurityManagerPtr*
+virSecurityManagerGetNested(virSecurityManagerPtr mgr);
+
#endif /* VIR_SECURITY_MANAGER_H__ */
char *scontext = NULL;
context_t ctx = NULL;
const char *range;
- virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
+ virSecurityLabelDefPtr seclabel;
+ virSecuritySELinuxDataPtr data;
- VIR_DEBUG("driver=%s", virSecurityManagerGetDriver(mgr));
- if ((def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC) &&
- !def->seclabels[0]->baselabel &&
- def->seclabels[0]->model) {
+ if (mgr == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("security model already defined for VM"));
+ "%s", _("invalid security driver"));
return rc;
}
- if (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
- def->seclabels[0]->label) {
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (seclabel == NULL) {
+ return rc;
+ }
+
+ data = virSecurityManagerGetPrivateData(mgr);
+
+ VIR_DEBUG("label=%s", virSecurityManagerGetDriver(mgr));
+ if (seclabel->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
+ seclabel->label) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("security label already defined for VM"));
return rc;
}
- if (def->seclabels[0]->imagelabel) {
+ if (seclabel->imagelabel) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("security image label already defined for VM"));
return rc;
}
- if (def->seclabels[0]->model &&
- STRNEQ(def->seclabels[0]->model, SECURITY_SELINUX_NAME)) {
+ if (seclabel->model &&
+ STRNEQ(seclabel->model, SECURITY_SELINUX_NAME)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("security label model %s is not supported with selinux"),
- def->seclabels[0]->model);
+ seclabel->model);
return rc;
}
- VIR_DEBUG("type%d", def->seclabels[0]->type);
+ VIR_DEBUG("type=%d", seclabel->type);
- switch (def->seclabels[0]->type) {
+ switch (seclabel->type) {
case VIR_DOMAIN_SECLABEL_STATIC:
- if (!(ctx = context_new(def->seclabels[0]->label)) ) {
+ if (!(ctx = context_new(seclabel->label)) ) {
virReportSystemError(errno,
_("unable to allocate socket security context '%s'"),
- def->seclabels[0]->label);
+ seclabel->label);
return rc;
}
if (virSecuritySELinuxMCSAdd(mgr, mcs) < 0)
goto cleanup;
- def->seclabels[0]->label =
- virSecuritySELinuxGenNewContext(def->seclabels[0]->baselabel ?
- def->seclabels[0]->baselabel :
- data->domain_context, mcs, false);
- if (! def->seclabels[0]->label) {
+ seclabel->label =
+ virSecuritySELinuxGenNewContext(seclabel->baselabel ?
+ seclabel->baselabel :
+ data->domain_context, mcs, false);
+ if (!seclabel->label) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot generate selinux context for %s"), mcs);
goto cleanup;
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected security label type '%s'"),
- virDomainSeclabelTypeToString(def->seclabels[0]->type));
+ virDomainSeclabelTypeToString(seclabel->type));
goto cleanup;
}
- if (!def->seclabels[0]->norelabel) {
- def->seclabels[0]->imagelabel = virSecuritySELinuxGenNewContext(data->file_context,
- mcs,
- true);
- if (!def->seclabels[0]->imagelabel) {
+ if (!seclabel->norelabel) {
+ seclabel->imagelabel = virSecuritySELinuxGenNewContext(data->domain_context,
+ mcs,
+ true);
+ if (!seclabel->imagelabel) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot generate selinux context for %s"), mcs);
goto cleanup;
}
}
- if (!def->seclabels[0]->model &&
- !(def->seclabels[0]->model = strdup(SECURITY_SELINUX_NAME))) {
+ if (!seclabel->model &&
+ !(seclabel->model = strdup(SECURITY_SELINUX_NAME))) {
virReportOOMError();
goto cleanup;
}
cleanup:
if (rc != 0) {
- if (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC)
- VIR_FREE(def->seclabels[0]->label);
- VIR_FREE(def->seclabels[0]->imagelabel);
- if (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
- !def->seclabels[0]->baselabel)
- VIR_FREE(def->seclabels[0]->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)
VIR_FREE(mcs);
VIR_DEBUG("model=%s label=%s imagelabel=%s baselabel=%s",
- NULLSTR(def->seclabels[0]->model),
- NULLSTR(def->seclabels[0]->label),
- NULLSTR(def->seclabels[0]->imagelabel),
- NULLSTR(def->seclabels[0]->baselabel));
+ NULLSTR(seclabel->model),
+ NULLSTR(seclabel->label),
+ NULLSTR(seclabel->imagelabel),
+ NULLSTR(seclabel->baselabel));
return rc;
}
context_t ctx = NULL;
const char *mcs;
int rv;
+ virSecurityLabelDefPtr seclabel;
- if (def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_STATIC)
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (seclabel == NULL) {
+ return -1;
+ }
+
+ if (seclabel->type == VIR_DOMAIN_SECLABEL_STATIC)
return 0;
if (getpidcon(pid, &pctx) == -1) {
virDomainDiskDefPtr disk,
int migrated)
{
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ virSecurityLabelDefPtr seclabel;
+ virSecurityDeviceLabelDefPtr disk_seclabel;
+
+ seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (seclabel == NULL)
+ return -1;
- if (secdef->norelabel || (disk->seclabels[0] && disk->seclabels[0]->norelabel))
+ 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
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->seclabels[0] && disk->seclabels[0]->norelabel)
+ disk_seclabel = virDomainDiskDefGetSecurityLabelDef(disk,
+ SECURITY_SELINUX_NAME);
+
+ if (disk_seclabel && disk_seclabel->norelabel)
return 0;
- if (disk->seclabels[0] && !disk->seclabels[0]->norelabel &&
- disk->seclabels[0]->label) {
- ret = virSecuritySELinuxSetFilecon(path, disk->seclabels[0]->label);
+ if (disk_seclabel && !disk_seclabel->norelabel &&
+ disk_seclabel->label) {
+ ret = virSecuritySELinuxSetFilecon(path, disk_seclabel->label);
} else if (depth == 0) {
if (disk->shared) {
} else {
ret = virSecuritySELinuxSetFileconOptional(path, data->content_context);
}
- if (ret == 1 && !disk->seclabels[0]) {
+ 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->seclabels[0]) < 0) {
+ if (VIR_ALLOC(disk_seclabel) < 0) {
virReportOOMError();
return -1;
}
- disk->seclabels[0]->norelabel = true;
+ disk_seclabel->norelabel = true;
ret = 0;
}
return ret;
virDomainDiskDefPtr disk)
{
+ bool allowDiskFormatProbing;
virSecuritySELinuxCallbackData cbdata;
- cbdata.secdef = def->seclabels[0];
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;
virSecuritySELinuxSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
const char *file, void *opaque)
{
+ virSecurityLabelDefPtr secdef;
virDomainDefPtr def = opaque;
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
return virSecuritySELinuxSetFilecon(file, secdef->imagelabel);
}
virSecuritySELinuxSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
const char *file, void *opaque)
{
+ virSecurityLabelDefPtr secdef;
virDomainDefPtr def = opaque;
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
return virSecuritySELinuxSetFilecon(file, secdef->imagelabel);
}
virDomainHostdevDefPtr dev)
{
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ virSecurityLabelDefPtr secdef;
int ret = -1;
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
+
if (secdef->norelabel)
return 0;
virDomainHostdevDefPtr dev)
{
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ virSecurityLabelDefPtr secdef;
int ret = -1;
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
+
if (secdef->norelabel)
return 0;
virDomainChrSourceDefPtr dev)
{
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ 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;
virDomainChrSourceDefPtr dev)
{
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ 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;
virDomainDefPtr def,
int migrated ATTRIBUTE_UNUSED)
{
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ 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;
virSecuritySELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def)
{
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
if (secdef->type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
if (secdef->label != NULL) {
virDomainDefPtr def,
const char *savefile)
{
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
if (secdef->norelabel)
return 0;
virDomainDefPtr def,
const char *savefile)
{
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
if (secdef->norelabel)
return 0;
virSecuritySELinuxSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainDefPtr def)
{
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
+
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
virDomainDefPtr def)
{
/* TODO: verify DOI */
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
- VIR_DEBUG("label=%s", secdef->label);
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
- if (def->seclabels[0]->label == NULL)
+ if (secdef->label == NULL)
return 0;
+ VIR_DEBUG("label=%s", secdef->label);
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
virDomainDefPtr def)
{
/* TODO: verify DOI */
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ virSecurityLabelDefPtr secdef;
context_t execcon = NULL;
context_t proccon = NULL;
security_context_t scon = NULL;
int rc = -1;
- if (def->seclabels[0]->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)) {
virSecuritySELinuxSetSecuritySocketLabel(virSecurityManagerPtr mgr,
virDomainDefPtr vm)
{
- const virSecurityLabelDefPtr secdef = vm->seclabels[0];
+ virSecurityLabelDefPtr secdef;
int rc = -1;
+ secdef = virDomainDefGetSecurityLabelDef(vm, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
+
if (secdef->label == NULL)
return 0;
virDomainDefPtr def)
{
/* TODO: verify DOI */
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
- if (def->seclabels[0]->label == NULL)
+ if (secdef->label == NULL)
return 0;
if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virDomainDefPtr def,
const char *stdin_path)
{
- virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
int i;
+ virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr);
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
if (secdef->norelabel)
return 0;
virDomainDefPtr def,
int fd)
{
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return -1;
if (secdef->imagelabel == NULL)
return 0;
virSecuritySELinuxGenImageLabel(virSecurityManagerPtr mgr,
virDomainDefPtr def)
{
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ 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) {
virDomainDefPtr def)
{
char *opts = NULL;
- const virSecurityLabelDefPtr secdef = def->seclabels[0];
+ virSecurityLabelDefPtr secdef;
+
+ secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
+ if (secdef == NULL)
+ return NULL;
if (! secdef->imagelabel)
secdef->imagelabel = virSecuritySELinuxGenImageLabel(mgr,def);
#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
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;
}
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
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;
+ break;
+ }
+ }
return rc;
}
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
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)
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)
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;
}
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;
}
{
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
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;
}
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;
}
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;
}
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;
}
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 = {
.privateDataLen = sizeof(virSecurityStackData),
.name = "stack",
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 */