static int SELinuxGetSecurityProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, virDomainObjPtr vm, virSecurityLabelPtr sec) { security_context_t ctx; if (getpidcon(vm->pid, &ctx) == -1) { virReportSystemError(errno, _("unable to get PID %d security context"), vm->pid); return -1; } if (strlen((char *) ctx) >= VIR_SECURITY_LABEL_BUFLEN) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, _("security label exceeds " "maximum length: %d"), VIR_SECURITY_LABEL_BUFLEN - 1); freecon(ctx); return -1; } strcpy(sec->label, (char *) ctx); freecon(ctx); sec->enforcing = security_getenforce(); if (sec->enforcing == -1) { virReportSystemError(errno, "%s", _("error calling security_getenforce()")); return -1; } return 0; }
int virSecurityDriverSetDOI(virSecurityDriverPtr drv, const char *doi) { if (strlen(doi) >= VIR_SECURITY_DOI_BUFLEN) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, _("%s: DOI \'%s\' is " "longer than the maximum allowed length of %d"), __func__, doi, VIR_SECURITY_DOI_BUFLEN - 1); return -1; } strcpy(drv->_private.doi, doi); return 0; }
int virSecurityDriverVerify(virDomainDefPtr def) { unsigned int i; const virSecurityLabelDefPtr secdef = &def->seclabel; if (!secdef->model || STREQ(secdef->model, "none")) return 0; for (i = 0; security_drivers[i] != NULL ; i++) { if (STREQ(security_drivers[i]->name, secdef->model)) { return security_drivers[i]->domainSecurityVerify(def); } } virSecurityReportError(VIR_ERR_XML_ERROR, _("invalid security model '%s'"), secdef->model); return -1; }
static int SELinuxGenSecurityLabel(virSecurityManagerPtr mgr, virDomainDefPtr def) { int rc = -1; char *mcs = NULL; char *scontext = NULL; int c1 = 0; int c2 = 0; context_t ctx = NULL; const char *range; virSecuritySELinuxDataPtr data = virSecurityManagerGetPrivateData(mgr); VIR_DEBUG("SELinuxGenSecurityLabel %s", virSecurityManagerGetDriver(mgr)); if ((def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) && !def->seclabel.baselabel && def->seclabel.model) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("security model already defined for VM")); return rc; } if (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC && def->seclabel.label) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("security label already defined for VM")); return rc; } if (def->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)) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, _("security label model %s is not supported with selinux"), def->seclabel.model); return rc; } VIR_DEBUG("SELinuxGenSecurityLabel %d", def->seclabel.type); switch (def->seclabel.type) { case VIR_DOMAIN_SECLABEL_STATIC: if (!(ctx = context_new(def->seclabel.label)) ) { virReportSystemError(errno, _("unable to allocate socket security context '%s'"), def->seclabel.label); return rc; } range = context_range_get(ctx); if (!range || !(mcs = strdup(range))) { virReportOOMError(); goto cleanup; } break; case VIR_DOMAIN_SECLABEL_DYNAMIC: do { c1 = virRandomBits(10); c2 = virRandomBits(10); if ( c1 == c2 ) { if (virAsprintf(&mcs, "s0:c%d", c1) < 0) { virReportOOMError(); goto cleanup; } } else { if (c1 > c2) { c1 ^= c2; c2 ^= c1; c1 ^= c2; } if (virAsprintf(&mcs, "s0:c%d,c%d", c1, c2) < 0) { virReportOOMError(); goto cleanup; } } } while (mcsAdd(mcs) == -1); def->seclabel.label = SELinuxGenNewContext(def->seclabel.baselabel ? def->seclabel.baselabel : data->domain_context, mcs); if (! def->seclabel.label) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, _("cannot generate selinux context for %s"), mcs); goto cleanup; } break; case VIR_DOMAIN_SECLABEL_NONE: /* no op */ break; default: virSecurityReportError(VIR_ERR_INTERNAL_ERROR, _("unexpected security label type '%s'"), virDomainSeclabelTypeToString(def->seclabel.type)); goto cleanup; } if (!def->seclabel.norelabel) { def->seclabel.imagelabel = SELinuxGenNewContext(data->file_context, mcs); if (!def->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))) { virReportOOMError(); goto cleanup; } rc = 0; 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 (ctx) context_free(ctx); VIR_FREE(scontext); 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)); return rc; }
static int SELinuxGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, virDomainObjPtr vm) { int rc = -1; char *mcs = NULL; char *scontext = NULL; int c1 = 0; int c2 = 0; context_t ctx = NULL; if ((vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) && !vm->def->seclabel.baselabel && vm->def->seclabel.model) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("security model already defined for VM")); return rc; } if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC && vm->def->seclabel.label) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("security label already defined for VM")); return rc; } if (vm->def->seclabel.imagelabel) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("security image label already defined for VM")); return rc; } if (vm->def->seclabel.model && STRNEQ(vm->def->seclabel.model, SECURITY_SELINUX_NAME)) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, _("security label model %s is not supported with selinux"), vm->def->seclabel.model); return rc; } if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC) { if (!(ctx = context_new(vm->def->seclabel.label)) ) { virReportSystemError(errno, _("unable to allocate socket security context '%s'"), vm->def->seclabel.label); return rc; } const char *range = context_range_get(ctx); if (!range || !(mcs = strdup(range))) { virReportOOMError(); goto cleanup; } } else { do { c1 = virRandom(1024); c2 = virRandom(1024); if ( c1 == c2 ) { if (virAsprintf(&mcs, "s0:c%d", c1) < 0) { virReportOOMError(); goto cleanup; } } else { if (c1 > c2) { c1 ^= c2; c2 ^= c1; c1 ^= c2; } if (virAsprintf(&mcs, "s0:c%d,c%d", c1, c2) < 0) { virReportOOMError(); goto cleanup; } } } while (mcsAdd(mcs) == -1); vm->def->seclabel.label = SELinuxGenNewContext(vm->def->seclabel.baselabel ? vm->def->seclabel.baselabel : default_domain_context, mcs); if (! vm->def->seclabel.label) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, _("cannot generate selinux context for %s"), mcs); goto cleanup; } } vm->def->seclabel.imagelabel = SELinuxGenNewContext(default_image_context, mcs); if (!vm->def->seclabel.imagelabel) { virSecurityReportError(VIR_ERR_INTERNAL_ERROR, _("cannot generate selinux context for %s"), mcs); goto cleanup; } if (!vm->def->seclabel.model && !(vm->def->seclabel.model = strdup(SECURITY_SELINUX_NAME))) { virReportOOMError(); goto cleanup; } rc = 0; cleanup: if (rc != 0) { if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) VIR_FREE(vm->def->seclabel.label); VIR_FREE(vm->def->seclabel.imagelabel); if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC && !vm->def->seclabel.baselabel) VIR_FREE(vm->def->seclabel.model); } if (ctx) context_free(ctx); VIR_FREE(scontext); VIR_FREE(mcs); VIR_DEBUG("model=%s label=%s imagelabel=%s baselabel=%s", NULLSTR(vm->def->seclabel.model), NULLSTR(vm->def->seclabel.label), NULLSTR(vm->def->seclabel.imagelabel), NULLSTR(vm->def->seclabel.baselabel)); return rc; }