Exemplo n.º 1
0
int virSecurityManagerVerify(virSecurityManagerPtr mgr,
                             virDomainDefPtr def)
{
    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
     */
    secdef = virDomainDefGetSecurityLabelDef(def, mgr->drv->name);
    if (secdef == NULL || secdef->model == NULL)
        return 0;

    if (mgr->drv->domainSecurityVerify) {
        int ret;
        virObjectLock(mgr);
        ret = mgr->drv->domainSecurityVerify(mgr, def);
        virObjectUnlock(mgr);
        return ret;
    }

    virReportUnsupportedError();
    return -1;
}
Exemplo n.º 2
0
/* returns 1 if label isn't found, 0 on success, -1 on error */
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 || seclabel->imagelabel == NULL) {
        VIR_DEBUG("DAC imagelabel for domain '%s' wasn't found", def->name);
        return 1;
    }

    if (parseIds(seclabel->imagelabel, &uid, &gid) < 0)
        return -1;

    if (uidPtr)
        *uidPtr = uid;
    if (gidPtr)
        *gidPtr = gid;

    return 0;
}
Exemplo n.º 3
0
int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
                               virDomainDefPtr vm)
{
    int rc = 0;
    size_t i;
    virSecurityManagerPtr* sec_managers = NULL;
    virSecurityLabelDefPtr seclabel;

    if (mgr == NULL || mgr->drv == NULL)
        return -1;

    if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL)
        return -1;

    virObjectLock(mgr);
    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;
                seclabel->norelabel = true;
            }
        }

        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:
    virObjectUnlock(mgr);
    VIR_FREE(sec_managers);
    return rc;
}
Exemplo n.º 4
0
static int
AppArmorSetSecurityHostdevLabelHelper(const char *file, void *opaque)
{
    struct SDPDOP *ptr = opaque;
    virDomainDefPtr def = ptr->def;

    if (reload_profile(ptr->mgr, def, file, true) < 0) {
        virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(
                                                def, SECURITY_APPARMOR_NAME);
        if (!secdef) {
            virReportOOMError();
            return -1;
        }
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot update AppArmor profile \'%s\'"),
                       secdef->imagelabel);
        return -1;
    }
    return 0;
}
Exemplo n.º 5
0
/* reload the profile, adding read/write file specified by fn if it is not
 * NULL.
 */
static int
reload_profile(virSecurityManagerPtr mgr,
               virDomainDefPtr def,
               const char *fn,
               bool append)
{
    int rc = -1;
    char *profile_name = NULL;
    virSecurityLabelDefPtr secdef = virDomainDefGetSecurityLabelDef(
                                                def, SECURITY_APPARMOR_NAME);

    if (!secdef)
        return rc;

    if (secdef->norelabel)
        return 0;

    if ((profile_name = get_profile_name(def)) == NULL)
        return rc;

    /* Update the profile only if it is loaded */
    if (profile_loaded(secdef->imagelabel) >= 0) {
        if (load_profile(mgr, secdef->imagelabel, def, fn, append) < 0) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("cannot update AppArmor profile "
                             "\'%s\'"),
                           secdef->imagelabel);
            goto cleanup;
        }
    }

    rc = 0;
 cleanup:
    VIR_FREE(profile_name);

    return rc;
}
Exemplo n.º 6
0
int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
                               virDomainDefPtr vm)
{
    int ret = -1;
    size_t i, j;
    virSecurityManagerPtr* sec_managers = NULL;
    virSecurityLabelDefPtr seclabel;
    bool generated = false;

    if (mgr == NULL || mgr->drv == NULL)
        return ret;

    if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL)
        return ret;

    virObjectLock(mgr);
    for (i = 0; i < vm->nseclabels; i++) {
        if (!vm->seclabels[i]->model)
            continue;

        for (j = 0; sec_managers[j]; j++)
            if (STREQ(vm->seclabels[i]->model, sec_managers[j]->drv->name))
                break;

        if (!sec_managers[j]) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("Unable to find security driver for label %s"),
                           vm->seclabels[i]->model);
            goto cleanup;
        }
    }

    for (i = 0; sec_managers[i]; i++) {
        generated = false;
        seclabel = virDomainDefGetSecurityLabelDef(vm, sec_managers[i]->drv->name);
        if (!seclabel) {
            if (!(seclabel = virSecurityLabelDefNew(sec_managers[i]->drv->name)))
                goto cleanup;
            generated = seclabel->implicit = true;
        }

        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;
                seclabel->norelabel = true;
            }
        }

        if (seclabel->type == VIR_DOMAIN_SECLABEL_NONE) {
            if (sec_managers[i]->requireConfined) {
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                               _("Unconfined guests are not allowed on this host"));
                goto cleanup;
            } else if (vm->nseclabels && generated) {
                VIR_DEBUG("Skipping auto generated seclabel of type none");
                virSecurityLabelDefFree(seclabel);
                seclabel = NULL;
                continue;
            }
        }

        if (!sec_managers[i]->drv->domainGenSecurityLabel) {
            virReportUnsupportedError();
            virSecurityLabelDefFree(seclabel);
            seclabel = NULL;
        } else {
            /* The seclabel must be added to @vm prior calling domainGenSecurityLabel
             * which may require seclabel to be presented already */
            if (generated &&
                VIR_APPEND_ELEMENT(vm->seclabels, vm->nseclabels, seclabel) < 0)
                goto cleanup;

            if (sec_managers[i]->drv->domainGenSecurityLabel(sec_managers[i], vm) < 0) {
                if (VIR_DELETE_ELEMENT(vm->seclabels,
                                       vm->nseclabels -1, vm->nseclabels) < 0)
                    vm->nseclabels--;
                goto cleanup;
            }

            seclabel = NULL;
        }
    }

    ret = 0;

 cleanup:
    virObjectUnlock(mgr);
    if (generated)
        virSecurityLabelDefFree(seclabel);
    VIR_FREE(sec_managers);
    return ret;
}