提交 4e365df4 编写于 作者: D Daniel P. Berrange

Honour current sensitivity and category ranges in SELinux label generation

Currently the dynamic label generation code will create labels
with a sensitivity of s0, and a category pair in the range
0-1023. This is fine when running a standard MCS policy because
libvirtd will run with a label

  system_u:system_r:virtd_t:s0-s0:c0.c1023

With custom policies though, it is possible for libvirtd to have
a different sensitivity, or category range. For example

  system_u:system_r:virtd_t:s2-s3:c512.c1023

In this case we must assign the VM a sensitivity matching the
current lower sensitivity value, and categories in the range
512-1023
Signed-off-by: NDaniel P. Berrange <berrange@redhat.com>
上级 2d9df4fc
...@@ -106,13 +106,108 @@ virSecuritySELinuxMCSFind(virSecurityManagerPtr mgr) ...@@ -106,13 +106,108 @@ virSecuritySELinuxMCSFind(virSecurityManagerPtr mgr)
int c1 = 0; int c1 = 0;
int c2 = 0; int c2 = 0;
char *mcs = NULL; char *mcs = NULL;
security_context_t ourSecContext = NULL;
context_t ourContext = NULL;
char *sens, *cat, *tmp;
int catMin, catMax, catRange;
if (getcon(&ourSecContext) < 0) {
virReportSystemError(errno, "%s",
_("Unable to get current process SELinux context"));
goto cleanup;
}
if (!(ourContext = context_new(ourSecContext))) {
virReportSystemError(errno,
_("Unable to parse current SELinux context '%s'"),
ourSecContext);
goto cleanup;
}
if (!(sens = strdup(context_range_get(ourContext)))) {
virReportOOMError();
goto cleanup;
}
/* Find and blank out the category part */
if (!(tmp = strchr(sens, ':'))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Cannot parse sensitivity level in %s"),
sens);
goto cleanup;
}
*tmp = '\0';
cat = tmp + 1;
/* Find and blank out the sensitivity upper bound */
if ((tmp = strchr(sens, '-')))
*tmp = '\0';
/* sens now just contains the sensitivity lower bound */
/* Find & extract category min */
tmp = cat;
if (tmp[0] != 'c') {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Cannot parse category in %s"),
cat);
goto cleanup;
}
tmp++;
if (virStrToLong_i(tmp, &tmp, 10, &catMin) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Cannot parse category in %s"),
cat);
goto cleanup;
}
/* We *must* have a pair of categories otherwise
* there's no range to allocate VM categories from */
if (!tmp[0]) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("No category range available"));
goto cleanup;
}
/* Find & extract category max (if any) */
if (tmp[0] != '.') {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Cannot parse category in %s"),
cat);
goto cleanup;
}
tmp++;
if (tmp[0] != 'c') {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Cannot parse category in %s"),
cat);
goto cleanup;
}
tmp++;
if (virStrToLong_i(tmp, &tmp, 10, &catMax) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Cannot parse category in %s"),
cat);
goto cleanup;
}
/* +1 since virRandomInt range is exclusive of the upper bound */
catRange = (catMax - catMin) + 1;
if (catRange < 8) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Category range c%d-c%d too small"),
catMin, catMax);
goto cleanup;
}
VIR_DEBUG("Using sensitivity level '%s' cat min %d max %d range %d",
sens, catMin, catMax, catRange);
for (;;) { for (;;) {
c1 = virRandomBits(10); c1 = virRandomInt(catRange);
c2 = virRandomBits(10); c2 = virRandomInt(catRange);
VIR_DEBUG("Try cat %s:c%d,c%d", sens, c1+catMin, c2+catMin);
if (c1 == c2) { if (c1 == c2) {
if (virAsprintf(&mcs, "s0:c%d", c1) < 0) { if (virAsprintf(&mcs, "%s:c%d", sens, catMin + c1) < 0) {
virReportOOMError(); virReportOOMError();
return NULL; return NULL;
} }
...@@ -122,7 +217,7 @@ virSecuritySELinuxMCSFind(virSecurityManagerPtr mgr) ...@@ -122,7 +217,7 @@ virSecuritySELinuxMCSFind(virSecurityManagerPtr mgr)
c1 = c2; c1 = c2;
c2 = t; c2 = t;
} }
if (virAsprintf(&mcs, "s0:c%d,c%d", c1, c2) < 0) { if (virAsprintf(&mcs, "%s:c%d,c%d", sens, catMin + c1, catMin + c2) < 0) {
virReportOOMError(); virReportOOMError();
return NULL; return NULL;
} }
...@@ -136,6 +231,9 @@ virSecuritySELinuxMCSFind(virSecurityManagerPtr mgr) ...@@ -136,6 +231,9 @@ virSecuritySELinuxMCSFind(virSecurityManagerPtr mgr)
cleanup: cleanup:
VIR_DEBUG("Found context '%s'", NULLSTR(mcs)); VIR_DEBUG("Found context '%s'", NULLSTR(mcs));
VIR_FREE(sens);
freecon(ourSecContext);
context_free(ourContext);
return mcs; return mcs;
} }
...@@ -151,6 +249,9 @@ virSecuritySELinuxGenNewContext(const char *basecontext, ...@@ -151,6 +249,9 @@ virSecuritySELinuxGenNewContext(const char *basecontext,
security_context_t ourSecContext = NULL; security_context_t ourSecContext = NULL;
context_t ourContext = NULL; context_t ourContext = NULL;
VIR_DEBUG("basecontext=%s mcs=%s isObjectContext=%d",
basecontext, mcs, isObjectContext);
if (getcon(&ourSecContext) < 0) { if (getcon(&ourSecContext) < 0) {
virReportSystemError(errno, "%s", virReportSystemError(errno, "%s",
_("Unable to get current process SELinux context")); _("Unable to get current process SELinux context"));
...@@ -162,6 +263,7 @@ virSecuritySELinuxGenNewContext(const char *basecontext, ...@@ -162,6 +263,7 @@ virSecuritySELinuxGenNewContext(const char *basecontext,
ourSecContext); ourSecContext);
goto cleanup; goto cleanup;
} }
VIR_DEBUG("process=%s", ourSecContext);
if (!(context = context_new(basecontext))) { if (!(context = context_new(basecontext))) {
virReportSystemError(errno, virReportSystemError(errno,
...@@ -202,8 +304,7 @@ virSecuritySELinuxGenNewContext(const char *basecontext, ...@@ -202,8 +304,7 @@ virSecuritySELinuxGenNewContext(const char *basecontext,
virReportOOMError(); virReportOOMError();
goto cleanup; goto cleanup;
} }
VIR_DEBUG("Generated context '%s' from '%s' and '%s'", VIR_DEBUG("Generated context '%s'", ret);
ret, basecontext, ourSecContext);
cleanup: cleanup:
freecon(ourSecContext); freecon(ourSecContext);
context_free(ourContext); context_free(ourContext);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册