[libvirt] [sandbox PATCH] virt-sandbox patch to launch containers with proper label

Dan Walsh dwalsh at redhat.com
Fri Oct 4 20:15:02 UTC 2013


virt-sandbox should be launching containers based off the lxc_context
file from selinux-policy. I changed the hard coded paths to match the
latest fedora assigned labels.

Fedora 20 SELinux Policy and beyond will have proper SELinux labels in its
lxc_contexts file.
---
 bin/virt-sandbox-service                  | 34 ++++++++++++++--
 bin/virt-sandbox-service-clone.pod        |  5 +--
 bin/virt-sandbox-service-create.pod       | 16 +++++---
 bin/virt-sandbox.c                        |  5 +--
 libvirt-sandbox/libvirt-sandbox-builder.c | 68 +++++++++++++++++++++++++------
 5 files changed, 101 insertions(+), 27 deletions(-)

diff --git a/bin/virt-sandbox-service b/bin/virt-sandbox-service
index c4c4f54..0bfadfe 100755
--- a/bin/virt-sandbox-service
+++ b/bin/virt-sandbox-service
@@ -114,12 +114,32 @@ class Container:
         else:
             self.name = name
         self.dest = "%s/%s" % (self.path, self.name)
-        self.file_type = self.SELINUX_FILE_TYPE
+        self.init_selinux_types()
+        self.file_type = self.get_selinux_file_type()
         self.conn = None
         self.image = None
         self.uid = 0
         self.mounts = []
 
+    def init_selinux_types(self):
+        self.selinux_dict={}
+        fd = open(selinux.selinux_lxc_contexts_path(),"r")
+        records = fd.readlines()
+        fd.close()
+        for l in records:
+            try:
+                (name, val) = l.split("=")
+                self.selinux_dict[name.strip()]=val.strip()
+            except ValueError:
+                pass
+
+    def get_selinux_file_type(self):
+        try:
+            return self.selinux_dict["file"].split(":")[2]
+        except KeyError:
+            pass
+        return self.SELINUX_FILE_TYPE
+
     def get_file_type(self):
         return self.file_type
 
@@ -1072,9 +1092,17 @@ def default_security_opts():
     if selinux is None:
         return None
 
-    # XXX vary per URI for kvm/qemu/lxc.
+    label = "system_u:system_r:svirt_lxc_net_t:s0"
     # XXX generate a random category
-    return "static,label=system_u:system_r:svirt_lxc_net_t:s0"
+    try:
+        for uri in ("lxc", "qemu", "kvm"):
+            if self.uri.startswith(uri):
+                label = self.selinux_dict[uri]
+                break
+
+    except KeyError:
+        pass
+    return "static,label=%s" % label
 
 def gen_create_args(subparser):
     parser = subparser.add_parser("create",
diff --git a/bin/virt-sandbox-service-clone.pod b/bin/virt-sandbox-service-clone.pod
index cd261c4..3b4ecec 100644
--- a/bin/virt-sandbox-service-clone.pod
+++ b/bin/virt-sandbox-service-clone.pod
@@ -42,8 +42,7 @@ separated by commas. The following options are valid for SELinux
 
 Dynamically allocate an SELinux label, using the default base context.
 The default base context is system_u:system_r:svirt_lxc_net_t:s0 for LXC,
-system_u:system_r:svirt_t:s0 for KVM, system_u:system_r:svirt_tcg_t:s0
-for QEMU.
+system_u:system_r:svirt_qemu_net_t:s0 for KVM or QEMU.
 
 =item dynamic,label=USER:ROLE:TYPE:LEVEL
 
@@ -53,7 +52,7 @@ USER:ROLE:TYPE:LEVEL, instead of the default base context.
 =item static,label=USER:ROLE:TYPE:LEVEL
 
 To set a completely static label. For example,
-static,label=system_u:system_r:svirt_t:s0:c412,c355
+static,label=system_u:system_r:svirt_lxc_net_t:s0:c412,c355
 
 =back
 
diff --git a/bin/virt-sandbox-service-create.pod b/bin/virt-sandbox-service-create.pod
index 2ab289a..cbfd73d 100644
--- a/bin/virt-sandbox-service-create.pod
+++ b/bin/virt-sandbox-service-create.pod
@@ -61,7 +61,7 @@ Default: C<Login GID of UID>.
 
 Set SELinux file type to use within container.
 
-Default: C<svirt_lxc_file_t>.
+Default: C<svirt_sandbox_file_t>.
 
 =item B<-p PATH>, B<--path PATH>
 
@@ -180,10 +180,14 @@ separated by commas. The following options are valid for SELinux
 
 =item dynamic
 
-Dynamically allocate an SELinux label, using the default base context.
-The default base context is system_u:system_r:svirt_lxc_net_t:s0 for LXC,
-system_u:system_r:svirt_t:s0 for KVM, system_u:system_r:svirt_tcg_t:s0
-for QEMU.
+Dynamically allocate an SELinux label, using the default base context for the connection URI:
+The default base context are:
+
+B<LXC>  = system_u:system_r:svirt_lxc_net_t:s0 
+
+B<KVM> = system_u:system_r:svirt_kvm_net_t:s0
+
+B<QEMU> = system_u:system_r:svirt_qemu_net_t:s0
 
 =item dynamic,label=USER:ROLE:TYPE:LEVEL
 
@@ -193,7 +197,7 @@ USER:ROLE:TYPE:LEVEL, instead of the default base context.
 =item static,label=USER:ROLE:TYPE:LEVEL
 
 To set a completely static label. For example,
-static,label=system_u:system_r:svirt_t:s0:c412,c355
+static,label=system_u:system_r:svirt_lxc_net_t:s0:c412,c355
 
 =back
 
diff --git a/bin/virt-sandbox.c b/bin/virt-sandbox.c
index b16217b..f66b045 100644
--- a/bin/virt-sandbox.c
+++ b/bin/virt-sandbox.c
@@ -413,8 +413,7 @@ separated by commas. The following options are valid for SELinux
 
 Dynamically allocate an SELinux label, using the default base context.
 The default base context is system_u:system_r:svirt_lxc_net_t:s0 for LXC,
-system_u:system_r:svirt_t:s0 for KVM, system_u:system_r:svirt_tcg_t:s0
-for QEMU.
+system_u:system_r:svirt_qemu_net_t:s0 for KVM or QEMU.
 
 =item dynamic,label=USER:ROLE:TYPE:LEVEL
 
@@ -424,7 +423,7 @@ USER:ROLE:TYPE:LEVEL, instead of the default base context.
 =item static,label=USER:ROLE:TYPE:LEVEL
 
 To set a completely static label. For example,
-static,label=system_u:system_r:svirt_t:s0:c412,c355
+static,label=system_u:system_r:svirt_lxc_net_t:s0:c412,c355
 
 =item inherit
 
diff --git a/libvirt-sandbox/libvirt-sandbox-builder.c b/libvirt-sandbox/libvirt-sandbox-builder.c
index 1335042..b74f918 100644
--- a/libvirt-sandbox/libvirt-sandbox-builder.c
+++ b/libvirt-sandbox/libvirt-sandbox-builder.c
@@ -67,6 +67,53 @@ gvir_sandbox_builder_error_quark(void)
 {
     return g_quark_from_static_string("gvir-sandbox-builder");
 }
+#include <selinux/selinux.h>
+#include <errno.h>
+static char line[1024];
+
+static const char *get_label(int type, GError **error)
+{
+    const char *path = selinux_lxc_contexts_path();
+
+    GType gt = gvir_config_domain_virt_type_get_type ();
+    GEnumClass *cls = g_type_class_ref (gt);
+    GEnumValue *val = g_enum_get_value (cls, type);
+
+    FILE *fp = fopen(path, "r");
+    if (fp) {
+
+        while (val && fgets(line, sizeof line, fp)) {
+            int len = strlen(line);
+            if (len > 2)
+                continue;
+            if (line[len-1] == '\n')
+                line[len-1] = '\0';
+            char *name = line;
+            char *value = strchr(name, '=');
+            if (!value)
+                continue;
+            *value = '\0';
+            value++;
+            if (strcmp(name,val->value_nick))
+                continue;
+            return value;
+        }
+        fclose(fp);
+    }
+
+    switch (type) {
+    case GVIR_CONFIG_DOMAIN_VIRT_KVM:
+        return "system_u:system_r:svirt_kvm_net_t:s0";
+    case GVIR_CONFIG_DOMAIN_VIRT_QEMU:
+        return "system_u:system_r:svirt_qemu_net_t:s0";
+    case GVIR_CONFIG_DOMAIN_VIRT_LXC:
+        return "system_u:system_r:svirt_lxc_net_t:s0";
+    default:
+        *error = g_error_new(GVIR_SANDBOX_BUILDER_ERROR, 0,
+                             "No builder available for URI %s", val->value_nick);
+        return NULL;
+    }
+}
 
 static gboolean gvir_sandbox_builder_construct_domain(GVirSandboxBuilder *builder,
                                                       GVirSandboxConfig *config,
@@ -326,7 +373,7 @@ static gboolean gvir_sandbox_builder_construct_security(GVirSandboxBuilder *buil
                                                         GVirSandboxConfig *config G_GNUC_UNUSED,
                                                         const gchar *statedir G_GNUC_UNUSED,
                                                         GVirConfigDomain *domain,
-                                                        GError **error G_GNUC_UNUSED)
+                                                        GError **error)
 {
     GVirConfigDomainSeclabel *sec = gvir_config_domain_seclabel_new();
     const char *label = gvir_sandbox_config_get_security_label(config);
@@ -335,17 +382,14 @@ static gboolean gvir_sandbox_builder_construct_security(GVirSandboxBuilder *buil
     if (gvir_sandbox_config_get_security_dynamic(config)) {
         gvir_config_domain_seclabel_set_type(sec,
                                              GVIR_CONFIG_DOMAIN_SECLABEL_DYNAMIC);
-        if (label)
-            gvir_config_domain_seclabel_set_baselabel(sec, label);
-        else if (gvir_config_domain_get_virt_type(domain) ==
-                 GVIR_CONFIG_DOMAIN_VIRT_LXC)
-            gvir_config_domain_seclabel_set_baselabel(sec, "system_u:system_r:svirt_lxc_net_t:s0");
-        else if (gvir_config_domain_get_virt_type(domain) ==
-                 GVIR_CONFIG_DOMAIN_VIRT_QEMU)
-            gvir_config_domain_seclabel_set_baselabel(sec, "system_u:system_r:svirt_tcg_t:s0");
-        else if (gvir_config_domain_get_virt_type(domain) ==
-                 GVIR_CONFIG_DOMAIN_VIRT_KVM)
-            gvir_config_domain_seclabel_set_baselabel(sec, "system_u:system_r:svirt_t:s0");
+        if (!label)
+            label = get_label(gvir_config_domain_get_virt_type(domain), error);
+
+        if (!label)
+            return FALSE;
+
+        gvir_config_domain_seclabel_set_baselabel(sec, label);
+
     } else {
         gvir_config_domain_seclabel_set_type(sec,
                                              GVIR_CONFIG_DOMAIN_SECLABEL_STATIC);
-- 
1.8.3.1




More information about the libvir-list mailing list