All of lore.kernel.org
 help / color / mirror / Atom feed
* libvirt-selinux.patch
@ 2010-05-14 20:11 Daniel J Walsh
  2010-05-16  9:20 ` libvirt-selinux.patch Daniel P. Berrange
  0 siblings, 1 reply; 2+ messages in thread
From: Daniel J Walsh @ 2010-05-14 20:11 UTC (permalink / raw)
  To: Stephen Smalley, Paul Moore, SELinux, Berrange

[-- Attachment #1: Type: text/plain, Size: 883 bytes --]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This is my attempt at getting libvirt to work on an MLS machine.

This patch attempts to take the current context

libvirtcon = "system_u:system_r:virtd_t:SystemLow-SystemHigh"

The the label of the virtual machine

svirtcon = "system_u:system_r:virtd_t:TopSecret"

Create a new context

newcon = "system_u:system_r:virtd_t:TopSecret"

Then call setsockcreatecon(newcon)

Could you guys check the SELinux parts of this and make sure it matches
your expectations.

The patch does not work, because I think something is wrong with
libvirt, it does not call qemuConnectMonitor?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAkvtrm4ACgkQrlYvE4MpobOQ8gCcCeKTKyApgSUwZpfa4M/5XL7y
ucoAoONXiiG22C2oSekqLEnteusxwHsb
=NiF4
-----END PGP SIGNATURE-----

[-- Attachment #2: libvirt-selinux.patch --]
[-- Type: text/plain, Size: 7883 bytes --]

diff -up libvirt-0.8.1/src/qemu/qemu_driver.c~ libvirt-0.8.1/src/qemu/qemu_driver.c
--- libvirt-0.8.1/src/qemu/qemu_driver.c~	2010-04-30 11:45:43.000000000 -0400
+++ libvirt-0.8.1/src/qemu/qemu_driver.c	2010-05-14 11:48:38.000000000 -0400
@@ -1176,27 +1176,44 @@ static int
 qemuConnectMonitor(struct qemud_driver *driver, virDomainObjPtr vm)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    int ret;
+    int ret = -1;
 
     /* Hold an extra reference because we can't allow 'vm' to be
      * deleted while the monitor is active */
     virDomainObjRef(vm);
 
+    if ((driver->securityDriver &&
+         driver->securityDriver->domainSetSecuritySocketLabel &&
+         driver->securityDriver->domainSetSecuritySocketLabel(driver->securityDriver,vm)) < 0) {
+        VIR_ERROR(_("Failed to set security context for monitor for %s"), vm->def->name);
+        goto error;
+    }
+    
     if ((priv->mon = qemuMonitorOpen(vm,
                                      priv->monConfig,
                                      priv->monJSON,
                                      &monitorCallbacks)) == NULL) {
         VIR_ERROR(_("Failed to connect monitor for %s"), vm->def->name);
-        return -1;
+        goto error;
     }
 
+    if ((driver->securityDriver &&
+         driver->securityDriver->domainClearSecuritySocketLabel &&
+         driver->securityDriver->domainClearSecuritySocketLabel(driver->securityDriver,vm)) < 0) {
+        VIR_ERROR(_("Failed to set security context for monitor for %s"), vm->def->name);
+        goto error;
+    }
+    
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     ret = qemuMonitorSetCapabilities(priv->mon);
     qemuDomainObjExitMonitorWithDriver(driver, vm);
 
+    ret = 0;
+error:
     if (ret < 0) {
         qemuMonitorClose(priv->mon);
         priv->mon = NULL;
+        virDomainObjUnref(vm);
     }
 
     return ret;
diff -up libvirt-0.8.1/src/qemu/qemu_monitor.c~ libvirt-0.8.1/src/qemu/qemu_monitor.c
diff -up libvirt-0.8.1/src/security/security_driver.h~ libvirt-0.8.1/src/security/security_driver.h
--- libvirt-0.8.1/src/security/security_driver.h~	2010-03-18 08:30:08.000000000 -0400
+++ libvirt-0.8.1/src/security/security_driver.h	2010-05-13 17:20:43.000000000 -0400
@@ -32,6 +32,10 @@ typedef virSecurityDriverStatus (*virSec
 typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv);
 typedef int (*virSecurityDomainRestoreImageLabel) (virDomainObjPtr vm,
                                                    virDomainDiskDefPtr disk);
+typedef int (*virSecurityDomainSetSocketLabel) (virSecurityDriverPtr drv,
+                                                virDomainObjPtr vm);
+typedef int (*virSecurityDomainClearSocketLabel)(virSecurityDriverPtr drv,
+                                                virDomainObjPtr vm);
 typedef int (*virSecurityDomainSetImageLabel) (virDomainObjPtr vm,
                                                virDomainDiskDefPtr disk);
 typedef int (*virSecurityDomainRestoreHostdevLabel) (virDomainObjPtr vm,
@@ -59,6 +63,8 @@ struct _virSecurityDriver {
     virSecurityDriverOpen open;
     virSecurityDomainSecurityVerify domainSecurityVerify;
     virSecurityDomainRestoreImageLabel domainRestoreSecurityImageLabel;
+    virSecurityDomainSetSocketLabel domainSetSecuritySocketLabel;
+    virSecurityDomainClearSocketLabel domainClearSecuritySocketLabel;
     virSecurityDomainSetImageLabel domainSetSecurityImageLabel;
     virSecurityDomainGenLabel domainGenSecurityLabel;
     virSecurityDomainReserveLabel domainReserveSecurityLabel;
diff -up libvirt-0.8.1/src/security/security_selinux.c~ libvirt-0.8.1/src/security/security_selinux.c
--- libvirt-0.8.1/src/security/security_selinux.c~	2010-04-30 08:46:09.000000000 -0400
+++ libvirt-0.8.1/src/security/security_selinux.c	2010-05-14 11:47:38.000000000 -0400
@@ -730,6 +728,103 @@ SELinuxSetSecurityProcessLabel(virSecuri
 }
 
 static int
+SELinuxSetSecuritySocketLabel(virSecurityDriverPtr drv,
+                               virDomainObjPtr vm)
+{
+    /* TODO: verify DOI */
+    const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+    context_t execcon = NULL;
+    context_t proccon = NULL;
+    security_context_t scon = NULL;
+    int rc = -1;
+
+    if (vm->def->seclabel.label == NULL)
+        return 0;
+
+    if (!STREQ(drv->name, secdef->model)) {
+        virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("security label driver mismatch: "
+                                 "'%s' model configured for domain, but "
+                                 "hypervisor driver is '%s'."),
+                               secdef->model, drv->name);
+        goto done;
+    }
+
+    if ( !(execcon = context_new(secdef->label)) ) {
+        virReportSystemError(errno,
+                             _("unable to allocate socket security context '%s'"),
+                             secdef->label);
+        goto done;
+    }
+
+    if (getcon(&scon) == -1) {
+        virReportSystemError(errno,
+                             _("unable to get current process context '%s'"),
+                             secdef->label);
+        goto done;
+    }
+
+    if ( !(proccon = context_new(scon)) ) {
+        virReportSystemError(errno,
+                             _("unable to set socket security context '%s'"),
+                             secdef->label);
+        goto done;
+    }
+
+    if (context_range_set(proccon, context_range_get(execcon)) == -1) {
+        virReportSystemError(errno,
+                             _("unable to set socket security context range '%s'"),
+                             secdef->label);
+        goto done;
+    }
+
+    if (setsockcreatecon(context_str(proccon)) == -1) {
+        virReportSystemError(errno,
+                             _("unable to set socket security context '%s'"),
+                             context_str(proccon));
+        goto done;
+    }
+
+    rc = 0;
+done:
+    if (security_getenforce() != 1)
+        rc = 0;
+    if (execcon) context_free(execcon);
+    if (proccon) context_free(proccon);
+    freecon(scon);
+    return rc;
+}
+
+static int
+SELinuxClearSecuritySocketLabel(virSecurityDriverPtr drv,
+                                virDomainObjPtr vm)
+{
+    /* TODO: verify DOI */
+    const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
+    if (vm->def->seclabel.label == NULL)
+        return 0;
+
+    if (!STREQ(drv->name, secdef->model)) {
+        virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("security label driver mismatch: "
+                                 "'%s' model configured for domain, but "
+                                 "hypervisor driver is '%s'."),
+                               secdef->model, drv->name);
+        if (security_getenforce() == 1)
+            return -1;
+    }
+
+    if (setsockcreatecon(NULL) == -1) {
+        virReportSystemError(errno,
+                             _("unable to clear socket security context '%s'"),
+                             secdef->label);
+        if (security_getenforce() == 1)
+            return -1;
+    }
+    return 0;
+}
+
+static int
 SELinuxSetSecurityAllLabel(virDomainObjPtr vm)
 {
     const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
@@ -770,6 +865,8 @@ virSecurityDriver virSELinuxSecurityDriv
     .open                       = SELinuxSecurityDriverOpen,
     .domainSecurityVerify       = SELinuxSecurityVerify,
     .domainSetSecurityImageLabel = SELinuxSetSecurityImageLabel,
+    .domainSetSecuritySocketLabel     = SELinuxSetSecuritySocketLabel,
+    .domainClearSecuritySocketLabel     = SELinuxClearSecuritySocketLabel,
     .domainRestoreSecurityImageLabel = SELinuxRestoreSecurityImageLabel,
     .domainGenSecurityLabel     = SELinuxGenSecurityLabel,
     .domainReserveSecurityLabel     = SELinuxReserveSecurityLabel,

[-- Attachment #3: libvirt-selinux.patch.sig --]
[-- Type: application/pgp-signature, Size: 72 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-05-16  9:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-14 20:11 libvirt-selinux.patch Daniel J Walsh
2010-05-16  9:20 ` libvirt-selinux.patch Daniel P. Berrange

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.