};
static virSecuritySELinuxMCSPtr mcsList = NULL;
+/*
+ * Returns 0 on success, 1 if already reserved, or -1 on fatal error
+ */
static int
virSecuritySELinuxMCSAdd(const char *mcs)
{
for (ptr = mcsList; ptr; ptr = ptr->next) {
if (STREQ(ptr->mcs, mcs))
- return -1;
+ return 1;
}
- if (VIR_ALLOC(ptr) < 0)
+ if (VIR_ALLOC(ptr) < 0) {
+ virReportOOMError();
return -1;
- ptr->mcs = strdup(mcs);
+ }
+ if (!(ptr->mcs = strdup(mcs))) {
+ virReportOOMError();
+ VIR_FREE(ptr);
+ return -1;
+ }
ptr->next = mcsList;
mcsList = ptr;
return 0;
break;
case VIR_DOMAIN_SECLABEL_DYNAMIC:
- do {
+ for (;;) {
+ int rv;
c1 = virRandomBits(10);
c2 = virRandomBits(10);
goto cleanup;
}
}
- } while (virSecuritySELinuxMCSAdd(mcs) == -1);
+ if ((rv = virSecuritySELinuxMCSAdd(mcs)) < 0)
+ goto cleanup;
+ if (rv == 0)
+ break;
+ }
def->seclabel.label =
virSecuritySELinuxGenNewContext(def->seclabel.baselabel ?
security_context_t pctx;
context_t ctx = NULL;
const char *mcs;
+ int rv;
if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
return 0;
ctx = context_new(pctx);
freecon(pctx);
if (!ctx)
- goto err;
+ goto error;
mcs = context_range_get(ctx);
if (!mcs)
- goto err;
+ goto error;
+
+ if ((rv = virSecuritySELinuxMCSAdd(mcs)) < 0)
+ goto error;
- virSecuritySELinuxMCSAdd(mcs);
+ if (rv == 1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("MCS level for existing domain label %s already reserved"),
+ (char*)pctx);
+ goto error;
+ }
context_free(ctx);
return 0;
-err:
+error:
context_free(ctx);
return -1;
}