]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Add a test suite for validating SELinux labelling
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 19 Sep 2012 13:00:34 +0000 (14:00 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 14 Jan 2013 13:40:04 +0000 (13:40 +0000)
There are many aspects of the guest XML which result in the
SELinux driver applying file labelling. With the increasing
configuration options it is desirable to test this behaviour.
It is not possible to assume that the test suite has the
ability to set SELinux labels. Most filesystems though will
support extended attributes. Thus for the purpose of testing,
it is possible to extend the existing LD_PRELOAD hack to
override setfilecon() and getfilecon() to simply use the
'user.libvirt.selinux' attribute for the sake of testing.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
15 files changed:
.gitignore
HACKING
cfg.mk
configure.ac
libvirt.spec.in
m4/virt-attr.m4 [new file with mode: 0644]
tests/Makefile.am
tests/securityselinuxhelper.c
tests/securityselinuxlabeldata/chardev.txt [new file with mode: 0644]
tests/securityselinuxlabeldata/chardev.xml [new file with mode: 0644]
tests/securityselinuxlabeldata/disks.txt [new file with mode: 0644]
tests/securityselinuxlabeldata/disks.xml [new file with mode: 0644]
tests/securityselinuxlabeldata/kernel.txt [new file with mode: 0644]
tests/securityselinuxlabeldata/kernel.xml [new file with mode: 0644]
tests/securityselinuxlabeltest.c [new file with mode: 0644]

index 882ae4ca6b59afc59ad3a50e2e7d7ddcdb40eed0..a851616ad5aaad2b272a873aa55bd9866c81a8a9 100644 (file)
 /tests/secaatest
 /tests/seclabeltest
 /tests/securityselinuxtest
+/tests/securityselinuxlabeltest
 /tests/sexpr2xmltest
 /tests/shunloadtest
 /tests/sockettest
diff --git a/HACKING b/HACKING
index bf02b650762d39ee575849fee8540703c918eb95..3b800d81e14e5452c5b2e1d401a58045a96ce2ab 100644 (file)
--- a/HACKING
+++ b/HACKING
@@ -689,7 +689,7 @@ stick to the following general plan for all *.c source files:
   #include <string.h>
   #include <limits.h>
 
-  #if HAVE_NUMACTL                Some system includes aren't supported
+  #if WITH_NUMACTL                Some system includes aren't supported
   # include <numa.h>              everywhere so need these #if guards.
   #endif
 
diff --git a/cfg.mk b/cfg.mk
index ff9adcb1908bfc4f4a94a4a36019ac4b82269199..e42ef28c173a1dad4a4b6ae739aac2365ee47b7a 100644 (file)
--- a/cfg.mk
+++ b/cfg.mk
@@ -795,7 +795,7 @@ exclude_file_name_regexp--sc_prohibit_nonreentrant = \
   ^((po|tests)/|docs/.*py|run.in$$)
 
 exclude_file_name_regexp--sc_prohibit_raw_allocation = \
-  ^(src/util/viralloc\.[ch]|examples/.*)$$
+  ^(src/util/viralloc\.[ch]|examples/.*|tests/securityselinuxhelper.c)$$
 
 exclude_file_name_regexp--sc_prohibit_readlink = \
   ^src/(util/virutil|lxc/lxc_container)\.c$$
index 2cff5621060c8e592e630239f786e6b03b7a39de..27e99f40cf45d81a3d7775543dd7052e4c2f47dc 100644 (file)
@@ -143,6 +143,7 @@ AC_MSG_RESULT([$VERSION_SCRIPT_FLAGS])
 LIBVIRT_COMPILE_WARNINGS
 
 LIBVIRT_CHECK_APPARMOR
+LIBVIRT_CHECK_ATTR
 LIBVIRT_CHECK_AUDIT
 LIBVIRT_CHECK_AVAHI
 LIBVIRT_CHECK_BLKID
@@ -2467,6 +2468,7 @@ AC_MSG_NOTICE([])
 AC_MSG_NOTICE([Libraries])
 AC_MSG_NOTICE([])
 LIBVIRT_RESULT_APPARMOR
+LIBVIRT_RESULT_ATTR
 LIBVIRT_RESULT_AUDIT
 LIBVIRT_RESULT_AVAHI
 LIBVIRT_RESULT_BLKID
index 35869a8625ac8a78a4e0052f9b791a4121e9f9e3..6d5e9f1ccae6b3ca522a3dadebbb3814072a84a4 100644 (file)
@@ -410,6 +410,7 @@ BuildRequires: ncurses-devel
 BuildRequires: gettext
 BuildRequires: libtasn1-devel
 BuildRequires: gnutls-devel
+BuildRequires: libattr-devel
 %if 0%{?fedora} >= 12 || 0%{?rhel} >= 6
 # for augparse, optionally used in testing
 BuildRequires: augeas
diff --git a/m4/virt-attr.m4 b/m4/virt-attr.m4
new file mode 100644 (file)
index 0000000..341b35b
--- /dev/null
@@ -0,0 +1,9 @@
+dnl The libattr.so library
+
+AC_DEFUN([LIBVIRT_CHECK_ATTR],[
+  LIBVIRT_CHECK_LIB([ATTR], [attr], [getxattr], [attr/xattr.h])
+])
+
+AC_DEFUN([LIBVIRT_RESULT_ATTR],[
+  LIBVIRT_RESULT_LIB([ATTR])
+])
index 6f0dde52074d4d4f71ecaa3a0131cf46c6fb3bbb..61b0a0c2ff2947f9bc2178cd4a57a0210afee6f7 100644 (file)
@@ -68,6 +68,7 @@ EXTRA_DIST =          \
        qemuxml2argvdata \
        qemuxml2xmloutdata \
        qemuxmlnsdata \
+       securityselinuxlabeldata \
        schematestutils.sh \
        sexpr2xmldata \
        storagepoolschematest \
@@ -106,6 +107,9 @@ endif
 
 if WITH_SECDRIVER_SELINUX
 test_programs += securityselinuxtest
+if WITH_ATTR
+test_programs += securityselinuxlabeltest
+endif
 endif
 
 if WITH_DRIVER_MODULES
@@ -597,10 +601,20 @@ securityselinuxtest_SOURCES = \
        securityselinuxtest.c testutils.h testutils.c
 securityselinuxtest_CFLAGS = -Dabs_builddir="\"$(abs_builddir)\"" $(AM_CFLAGS)
 securityselinuxtest_LDADD = $(LDADDS)
-securityselinuxtest_DEPENDENCIES = libsecurityselinuxhelper.la
-else
-EXTRA_DIST += securityselinuxtest.c securityselinuxhelper.c
+securityselinuxtest_DEPENDENCIES = libsecurityselinuxhelper.la ../src/libvirt.la
+
+if WITH_QEMU
+if WITH_ATTR
+securityselinuxlabeltest_SOURCES = \
+       securityselinuxlabeltest.c testutils.h testutils.c \
+        testutilsqemu.h testutilsqemu.c
+securityselinuxlabeltest_CFLAGS = -Dabs_builddir="\"$(abs_builddir)\"" $(AM_CFLAGS)
+securityselinuxlabeltest_LDADD = $(qemu_LDADDS)
+securityselinuxlabeltest_DEPENDENCIES = libsecurityselinuxhelper.la ../src/libvirt.la
+endif
+endif
 endif
+EXTRA_DIST += securityselinuxtest.c securityselinuxlabeltest.c securityselinuxhelper.c
 
 virbuftest_SOURCES = \
        virbuftest.c testutils.h testutils.c
index dc63ff3d3a561b0423a7a06bd021ebb6fe85d8a1..daad7dd43fa74a28f8024c8db4a882a747f5bb51 100644 (file)
@@ -24,6 +24,9 @@
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
+#include <attr/xattr.h>
+
+
 /*
  * The kernel policy will not allow us to arbitrarily change
  * test process context. This helper is used as an LD_PRELOAD
@@ -64,3 +67,33 @@ int setcon_raw(security_context_t context)
 {
     return setenv("FAKE_CONTEXT", context, 1);
 }
+
+
+#if WITH_ATTR
+int setfilecon(const char *path, security_context_t con)
+{
+    const char *constr = con;
+    return setxattr(path, "user.libvirt.selinux",
+                    constr, strlen(constr), 0);
+}
+
+
+int getfilecon(const char *path, security_context_t *con)
+{
+    char *constr = NULL;
+    ssize_t len = getxattr(path, "user.libvirt.selinux",
+                           NULL, 0);
+    if (len < 0)
+        return -1;
+    if (!(constr = malloc(len+1)))
+        return -1;
+    memset(constr, 0, len);
+    if (getxattr(path, "user.libvirt.selinux", constr, len) < 0) {
+        free(constr);
+        return -1;
+    }
+    *con = constr;
+    constr[len] = '\0';
+    return 0;
+}
+#endif
diff --git a/tests/securityselinuxlabeldata/chardev.txt b/tests/securityselinuxlabeldata/chardev.txt
new file mode 100644 (file)
index 0000000..3f4b630
--- /dev/null
@@ -0,0 +1,7 @@
+/plain.txt;system_u:object_r:svirt_image_t:s0:c41,c264
+/plain.dev;system_u:object_r:svirt_image_t:s0:c41,c264
+/plain.fifo;system_u:object_r:svirt_image_t:s0:c41,c264
+/nolabel.sock;
+/plain.sock;
+/yeslabel.sock;system_u:object_r:svirt_image_t:s0:c41,c264
+/altlabel.sock;system_u:object_r:svirt_image_custom_t:s0:c41,c264
diff --git a/tests/securityselinuxlabeldata/chardev.xml b/tests/securityselinuxlabeldata/chardev.xml
new file mode 100644 (file)
index 0000000..64b6b5f
--- /dev/null
@@ -0,0 +1,47 @@
+<domain type='kvm'>
+  <name>vm1</name>
+  <uuid>c7b3edbd-edaf-9455-926a-d65c16db1800</uuid>
+  <memory unit='KiB'>219200</memory>
+  <os>
+    <type arch='i686' machine='pc-1.0'>hvm</type>
+    <boot dev='cdrom'/>
+  </os>
+  <devices>
+    <serial type='file'>
+      <source path='/plain.txt'/>
+    </serial>
+    <serial type='pipe'>
+      <source path='/plain.fifo'/>
+    </serial>
+    <serial type='dev'>
+      <source path='/plain.dev'/>
+    </serial>
+    <serial type='unix'>
+      <source mode='bind' path='/plain.sock'/>
+    </serial>
+    <serial type='unix'>
+      <source mode='connect' path='/nolabel.sock'>
+        <seclabel relabel='no' model='selinux'/>
+      </source>
+    </serial>
+    <serial type='unix'>
+      <source mode='connect' path='/yeslabel.sock'>
+      </source>
+    </serial>
+    <serial type='unix'>
+      <source mode='connect' path='/altlabel.sock'>
+        <seclabel relabel='yes' model='selinux'>
+          <label>system_u:object_r:svirt_image_custom_t:s0:c41,c264</label>
+        </seclabel>
+      </source>
+    </serial>
+    <input type='mouse' bus='ps2'/>
+    <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>
+      <listen type='address' address='0.0.0.0'/>
+    </graphics>
+  </devices>
+  <seclabel model="selinux" type="dynamic" relabel="yes">
+    <label>system_u:system_r:svirt_t:s0:c41,c264</label>
+    <imagelabel>system_u:object_r:svirt_image_t:s0:c41,c264</imagelabel>
+  </seclabel>
+</domain>
diff --git a/tests/securityselinuxlabeldata/disks.txt b/tests/securityselinuxlabeldata/disks.txt
new file mode 100644 (file)
index 0000000..2573d99
--- /dev/null
@@ -0,0 +1,5 @@
+/plain.raw;system_u:object_r:svirt_image_t:s0:c41,c264
+/shared.raw;system_u:object_r:svirt_image_t:s0
+/readonly.raw;system_u:object_r:virt_content_t:s0
+/nolabel.raw;
+/altlabel.raw;system_u:object_r:svirt_image_custom_t:s0:c41,c264
diff --git a/tests/securityselinuxlabeldata/disks.xml b/tests/securityselinuxlabeldata/disks.xml
new file mode 100644 (file)
index 0000000..33e8763
--- /dev/null
@@ -0,0 +1,52 @@
+<domain type='kvm'>
+  <name>vm1</name>
+  <uuid>c7b3edbd-edaf-9455-926a-d65c16db1800</uuid>
+  <memory unit='KiB'>219200</memory>
+  <os>
+    <type arch='i686' machine='pc-1.0'>hvm</type>
+    <boot dev='cdrom'/>
+  </os>
+  <devices>
+    <disk type='file' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source file='/plain.raw'/>
+      <target dev='vda' bus='virtio'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source file='/shared.raw'/>
+      <shareable/>
+      <target dev='vdb' bus='virtio'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source file='/readonly.raw'/>
+      <readonly/>
+      <target dev='vdc' bus='virtio'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source file='/nolabel.raw'>
+        <seclabel model='selinux' relabel='no'/>
+      </source>
+      <target dev='vdd' bus='virtio'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source file='/altlabel.raw'>
+        <seclabel model='selinux' relabel='yes'>
+          <label>system_u:object_r:svirt_image_custom_t:s0:c41,c264</label>
+        </seclabel>
+      </source>
+      <target dev='vde' bus='virtio'/>
+    </disk>
+    <input type='mouse' bus='ps2'/>
+    <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>
+      <listen type='address' address='0.0.0.0'/>
+    </graphics>
+  </devices>
+  <seclabel model="selinux" type="dynamic" relabel="yes">
+    <label>system_u:system_r:svirt_t:s0:c41,c264</label>
+    <imagelabel>system_u:object_r:svirt_image_t:s0:c41,c264</imagelabel>
+  </seclabel>
+</domain>
diff --git a/tests/securityselinuxlabeldata/kernel.txt b/tests/securityselinuxlabeldata/kernel.txt
new file mode 100644 (file)
index 0000000..87063fd
--- /dev/null
@@ -0,0 +1,2 @@
+/vmlinuz.raw;system_u:object_r:virt_content_t:s0
+/initrd.raw;system_u:object_r:virt_content_t:s0
diff --git a/tests/securityselinuxlabeldata/kernel.xml b/tests/securityselinuxlabeldata/kernel.xml
new file mode 100644 (file)
index 0000000..0fd551d
--- /dev/null
@@ -0,0 +1,20 @@
+<domain type='kvm'>
+  <name>vm1</name>
+  <uuid>c7b3edbd-edaf-9455-926a-d65c16db1800</uuid>
+  <memory unit='KiB'>219200</memory>
+  <os>
+    <type arch='i686' machine='pc-1.0'>hvm</type>
+    <kernel>/vmlinuz.raw</kernel>
+    <initrd>/initrd.raw</initrd>
+  </os>
+  <devices>
+    <input type='mouse' bus='ps2'/>
+    <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>
+      <listen type='address' address='0.0.0.0'/>
+    </graphics>
+  </devices>
+  <seclabel model="selinux" type="dynamic" relabel="yes">
+    <label>system_u:system_r:svirt_t:s0:c41,c264</label>
+    <imagelabel>system_u:object_r:svirt_image_t:s0:c41,c264</imagelabel>
+  </seclabel>
+</domain>
diff --git a/tests/securityselinuxlabeltest.c b/tests/securityselinuxlabeltest.c
new file mode 100644 (file)
index 0000000..b108860
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2011-2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * License along with this library;  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <selinux/selinux.h>
+#include <selinux/context.h>
+
+#include "internal.h"
+#include "testutils.h"
+#include "testutilsqemu.h"
+#include "qemu/qemu_domain.h"
+#include "viralloc.h"
+#include "virerror.h"
+#include "virfile.h"
+#include "virlog.h"
+#include "virutil.h"
+#include "security/security_manager.h"
+
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+static virCapsPtr caps;
+
+static virSecurityManagerPtr mgr;
+
+typedef struct testSELinuxFile testSELinuxFile;
+
+struct testSELinuxFile {
+    char *file;
+    char *context;
+};
+
+
+static int
+testSELinuxMungePath(char **path)
+{
+    char *tmp;
+
+    if (virAsprintf(&tmp, "%s/securityselinuxlabeldata%s",
+                    abs_srcdir, *path) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    VIR_FREE(*path);
+    *path = tmp;
+    return 0;
+}
+
+static int
+testSELinuxLoadFileList(const char *testname,
+                        testSELinuxFile **files,
+                        size_t *nfiles)
+{
+    int ret = -1;
+    char *path = NULL;
+    FILE *fp = NULL;
+
+    *files = NULL;
+    *nfiles = 0;
+
+    if (virAsprintf(&path, "%s/securityselinuxlabeldata/%s.txt",
+                    abs_srcdir, testname) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if (!(fp = fopen(path, "r"))) {
+        goto cleanup;
+    }
+
+    while (!feof(fp)) {
+        char *line;
+        char *file, *context;
+        if (VIR_ALLOC_N(line, 1024) < 0) {
+            virReportOOMError();
+            goto cleanup;
+        }
+        if (!fgets(line, 1024, fp)) {
+            if (!feof(fp))
+                goto cleanup;
+            break;
+        }
+
+        char *tmp = strchr(line, ';');
+        *tmp = '\0';
+        tmp++;
+
+        if (virAsprintf(&file, "%s/securityselinuxlabeldata%s", abs_builddir, line) < 0) {
+            VIR_FREE(line);
+            virReportOOMError();
+            goto cleanup;
+        }
+        if (*tmp != '\0' && *tmp != '\n') {
+            if (!(context = strdup(tmp))) {
+                VIR_FREE(line);
+                VIR_FREE(file);
+                virReportOOMError();
+                goto cleanup;
+            }
+
+            tmp = strchr(context, '\n');
+            *tmp = '\0';
+        } else {
+            context = NULL;
+        }
+
+        if (VIR_EXPAND_N(*files, *nfiles, 1) < 0) {
+            virReportOOMError();
+            goto cleanup;
+        }
+
+        (*files)[(*nfiles)-1].file = file;
+        (*files)[(*nfiles)-1].context = context;
+    }
+
+    ret = 0;
+
+cleanup:
+    VIR_FORCE_FCLOSE(fp);
+    VIR_FREE(path);
+    return ret;
+}
+
+
+static virDomainDefPtr
+testSELinuxLoadDef(const char *testname)
+{
+    char *xmlfile = NULL;
+    char *xmlstr = NULL;
+    virDomainDefPtr def = NULL;
+    size_t i;
+
+    if (virAsprintf(&xmlfile, "%s/securityselinuxlabeldata/%s.xml",
+                    abs_srcdir, testname) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if (virFileReadAll(xmlfile, 1024*1024, &xmlstr) < 0) {
+        goto cleanup;
+    }
+
+    if (!(def = virDomainDefParseString(caps, xmlstr,
+                                        QEMU_EXPECTED_VIRT_TYPES,
+                                        0)))
+        goto cleanup;
+
+    for (i = 0 ; i < def->ndisks ; i++) {
+        if (def->disks[i]->type != VIR_DOMAIN_DISK_TYPE_FILE &&
+            def->disks[i]->type != VIR_DOMAIN_DISK_TYPE_BLOCK)
+            continue;
+
+        if (testSELinuxMungePath(&def->disks[i]->src) < 0)
+            goto cleanup;
+    }
+
+    for (i = 0 ; i < def->nserials ; i++) {
+        if (def->serials[i]->source.type != VIR_DOMAIN_CHR_TYPE_FILE &&
+            def->serials[i]->source.type != VIR_DOMAIN_CHR_TYPE_PIPE &&
+            def->serials[i]->source.type != VIR_DOMAIN_CHR_TYPE_DEV &&
+            def->serials[i]->source.type != VIR_DOMAIN_CHR_TYPE_UNIX)
+            continue;
+
+        if (def->serials[i]->source.type == VIR_DOMAIN_CHR_TYPE_UNIX) {
+            if (testSELinuxMungePath(&def->serials[i]->source.data.nix.path) < 0)
+                goto cleanup;
+        } else {
+            if (testSELinuxMungePath(&def->serials[i]->source.data.file.path) < 0)
+                goto cleanup;
+        }
+    }
+
+    if (def->os.kernel &&
+        testSELinuxMungePath(&def->os.kernel) < 0)
+        goto cleanup;
+    if (def->os.initrd &&
+        testSELinuxMungePath(&def->os.initrd) < 0)
+        goto cleanup;
+
+cleanup:
+    VIR_FREE(xmlfile);
+    VIR_FREE(xmlstr);
+    return def;
+}
+
+
+static int
+testSELinuxCreateDisks(testSELinuxFile *files, size_t nfiles)
+{
+    size_t i;
+
+    if (virFileMakePath(abs_builddir "/securityselinuxlabeldata") < 0)
+        return -1;
+
+    for (i = 0 ; i < nfiles ; i++) {
+        if (virFileTouch(files[i].file, 0600) < 0)
+            return -1;
+    }
+    return 0;
+}
+
+static int
+testSELinuxDeleteDisks(testSELinuxFile *files, size_t nfiles)
+{
+    size_t i;
+
+    for (i = 0 ; i < nfiles ; i++) {
+        if (unlink(files[i].file) < 0)
+            return -1;
+    }
+    return 0;
+}
+
+static int
+testSELinuxCheckLabels(testSELinuxFile *files, size_t nfiles)
+{
+    size_t i;
+    security_context_t ctx;
+
+    for (i = 0 ; i < nfiles ; i++) {
+        if (getfilecon(files[i].file, &ctx) < 0) {
+            if (errno == ENODATA) {
+                ctx = NULL;
+            } else {
+                virReportSystemError(errno,
+                                     "Cannot read label on %s",
+                                     files[i].file);
+                return -1;
+            }
+        }
+        if (!STREQ_NULLABLE(files[i].context, ctx)) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           "File %s context '%s' did not match epected '%s'",
+                           files[i].file, ctx, files[i].context);
+            return -1;
+        }
+    }
+    return 0;
+}
+
+static int
+testSELinuxLabeling(const void *opaque)
+{
+    const char *testname = opaque;
+    int ret = -1;
+    testSELinuxFile *files = NULL;
+    size_t nfiles = 0;
+    size_t i;
+    virDomainDefPtr def = NULL;
+
+    if (testSELinuxLoadFileList(testname, &files, &nfiles) < 0)
+        goto cleanup;
+
+    if (testSELinuxCreateDisks(files, nfiles) < 0)
+        goto cleanup;
+
+    if (!(def = testSELinuxLoadDef(testname)))
+        goto cleanup;
+
+    if (virSecurityManagerSetAllLabel(mgr, def, NULL) < 0)
+        goto cleanup;
+
+    if (testSELinuxCheckLabels(files, nfiles) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+cleanup:
+    if (testSELinuxDeleteDisks(files, nfiles) < 0)
+        goto cleanup;
+
+    virDomainDefFree(def);
+    for (i = 0 ; i < nfiles; i++) {
+        VIR_FREE(files[i].file);
+        VIR_FREE(files[i].context);
+    }
+    VIR_FREE(files);
+    return ret;
+}
+
+
+
+static int
+mymain(void)
+{
+    int ret = 0;
+
+    if (!(mgr = virSecurityManagerNew("selinux", "QEMU", false, true, false))) {
+        virErrorPtr err = virGetLastError();
+        if (err->code == VIR_ERR_CONFIG_UNSUPPORTED)
+            exit(EXIT_AM_SKIP);
+
+        fprintf(stderr, "Unable to initialize security driver: %s\n",
+                err->message);
+        exit(EXIT_FAILURE);
+    }
+
+    if ((caps = testQemuCapsInit()) == NULL)
+        exit(EXIT_FAILURE);
+
+#define DO_TEST_LABELING(name) \
+    if (virtTestRun("Labelling " # name, 1, testSELinuxLabeling, name) < 0) \
+        ret = -1;                                                       \
+
+    setcon((security_context_t)"system_r:system_u:libvirtd_t:s0:c0.c1023");
+
+    DO_TEST_LABELING("disks");
+    DO_TEST_LABELING("kernel");
+    DO_TEST_LABELING("chardev");
+
+    return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/libsecurityselinuxhelper.so")