From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> 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: Daniel P. Berrange <berrange@xxxxxxxxxx> --- src/security/security_selinux.c | 88 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 4 deletions(-) diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index 4963ef5..714ec4d 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -106,13 +106,90 @@ virSecuritySELinuxMCSFind(virSecurityManagerPtr mgr) int c1 = 0; int c2 = 0; char *mcs = NULL; + security_context_t curseccontext = NULL; + context_t curcontext = NULL; + char *sens, *cat, *tmp; + int catMin, catMax, catRange; + + if (getcon(&curseccontext) < 0) { + virReportSystemError(errno, "%s", + _("Unable to get current process SELinux context")); + goto cleanup; + } + if (!(curcontext = context_new(curseccontext))) { + virReportSystemError(errno, + _("Unable to parse current SELinux context '%s'"), + curseccontext); + goto cleanup; + } + + if (!(sens = strdup(context_range_get(curcontext)))) { + 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 */ + 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; + } + 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; + } + + /* max is inclusive, hence the + 1 */ + catRange = (catMax - catMin) + 1; + + VIR_DEBUG("Using sensitivity level '%s' cat min %d max %d range %d", + sens, catMin, catMax, catRange); for (;;) { - c1 = virRandomBits(10); - c2 = virRandomBits(10); + c1 = virRandom(catRange); + c2 = virRandom(catRange); + VIR_DEBUG("Try cat %s:c%d,c%d", sens, c1, c2); if (c1 == c2) { - if (virAsprintf(&mcs, "s0:c%d", c1) < 0) { + if (virAsprintf(&mcs, "%s:c%d", sens, catMin + c1) < 0) { virReportOOMError(); return NULL; } @@ -122,7 +199,7 @@ virSecuritySELinuxMCSFind(virSecurityManagerPtr mgr) c2 ^= c1; c1 ^= c2; } - 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(); return NULL; } @@ -136,6 +213,9 @@ virSecuritySELinuxMCSFind(virSecurityManagerPtr mgr) cleanup: VIR_DEBUG("Found context '%s'", NULLSTR(mcs)); + VIR_FREE(sens); + freecon(curseccontext); + context_free(curcontext); return mcs; } -- 1.7.11.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list