]> xenbits.xensource.com Git - libvirt.git/commitdiff
Honour current user and role in SELinux label generation
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 9 Aug 2012 16:20:25 +0000 (17:20 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 14 Aug 2012 14:31:26 +0000 (15:31 +0100)
When generating an SELinux context for a VM from the template
"system_u:system_r:svirt_t:s0", copy the role + user from the
current process instead of the template context. So if the
current process is

   unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

then the VM context ends up as

  unconfined_u:unconfined_r:svirt_t:s0:c386,c703

instead of

   system_u:system_r:svirt_t:s0:c177,c424

Ideally the /etc/selinux/targeted/contexts/virtual_domain_context
file would have just shown the 'svirt_t' type, and not the full
context, but that can't be changed now for compatibility reasons.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/security/security_selinux.c

index 1b5c02ea02e0a05446c4af8b3408b5813b8c0aa2..70685282f4e46cb887bad1a7d6f760471a0156ff 100644 (file)
@@ -101,9 +101,23 @@ virSecuritySELinuxMCSRemove(virSecurityManagerPtr mgr,
 static char *
 virSecuritySELinuxGenNewContext(const char *basecontext, const char *mcs)
 {
-    context_t context;
+    context_t context = NULL;
     char *ret = NULL;
     char *str;
+    security_context_t ourSecContext = NULL;
+    context_t ourContext = NULL;
+
+    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 (!(context = context_new(basecontext))) {
         virReportSystemError(errno,
@@ -112,6 +126,22 @@ virSecuritySELinuxGenNewContext(const char *basecontext, const char *mcs)
         goto cleanup;
     }
 
+    if (context_user_set(context,
+                         context_user_get(ourContext)) != 0) {
+        virReportSystemError(errno,
+                             _("Unable to set SELinux context user '%s'"),
+                             context_user_get(ourContext));
+        goto cleanup;
+    }
+
+    if (context_role_set(context,
+                         context_role_get(ourContext)) != 0) {
+        virReportSystemError(errno,
+                             _("Unable to set SELinux context user '%s'"),
+                             context_role_get(ourContext));
+        goto cleanup;
+    }
+
     if (context_range_set(context, mcs) != 0) {
         virReportSystemError(errno,
                              _("Unable to set SELinux context MCS '%s'"),
@@ -127,7 +157,11 @@ virSecuritySELinuxGenNewContext(const char *basecontext, const char *mcs)
         virReportOOMError();
         goto cleanup;
     }
+    VIR_DEBUG("Generated context '%s' from '%s' and '%s'",
+              ret, basecontext, ourSecContext);
 cleanup:
+    freecon(ourSecContext);
+    context_free(ourContext);
     context_free(context);
     return ret;
 }