[libvirt] [PATCH 7/8] Honour current sensitivity and category ranges in SELinux label generation

Daniel P. Berrange berrange at redhat.com
Fri Aug 10 13:48:02 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

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 at redhat.com>
---
 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




More information about the libvir-list mailing list