]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
selinux: distinguish failure to label from request to avoid label
authorEric Blake <eblake@redhat.com>
Mon, 12 Aug 2013 15:15:42 +0000 (09:15 -0600)
committerEric Blake <eblake@redhat.com>
Tue, 20 Aug 2013 16:39:03 +0000 (10:39 -0600)
https://bugzilla.redhat.com/show_bug.cgi?id=924153

Commit 904e05a2 (v0.9.9) added a per-<disk> seclabel element with
an attribute relabel='no' in order to try and minimize the
impact of shutdown delays when an NFS server disappears.  The idea
was that if a disk is on NFS and can't be labeled in the first
place, there is no need to attempt the (no-op) relabel on domain
shutdown.  Unfortunately, the way this was implemented was by
modifying the domain XML so that the optimization would survive
libvirtd restart, but in a way that is indistinguishable from an
explicit user setting.  Furthermore, once the setting is turned
on, libvirt avoids attempts at labeling, even for operations like
snapshot or blockcopy where the chain is being extended or pivoted
onto non-NFS, where SELinux labeling is once again possible.  As
a result, it was impossible to do a blockcopy to pivot from an
NFS image file onto a local file.

The solution is to separate the semantics of a chain that must
not be labeled (which the user can set even on persistent domains)
vs. the optimization of not attempting a relabel on cleanup (a
live-only annotation), and using only the user's explicit notation
rather than the optimization as the decision on whether to skip
a label attempt in the first place.  When upgrading an older
libvirtd to a newer, an NFS volume will still attempt the relabel;
but as the avoidance of a relabel was only an optimization, this
shouldn't cause any problems.

In the ideal future, libvirt will eventually have XML describing
EVERY file in the backing chain, with each file having a separate
<seclabel> element.  At that point, libvirt will be able to track
more closely which files need a relabel attempt at shutdown.  But
until we reach that point, the single <seclabel> for the entire
<disk> chain is treated as a hint - when a chain has only one
file, then we know it is accurate; but if the chain has more than
one file, we have to attempt relabel in spite of the attribute,
in case part of the chain is local and SELinux mattered for that
portion of the chain.

* src/conf/domain_conf.h (_virSecurityDeviceLabelDef): Add new
member.
* src/conf/domain_conf.c (virSecurityDeviceLabelDefParseXML):
Parse it, for live images only.
(virSecurityDeviceLabelDefFormat): Output it.
(virDomainDiskDefParseXML, virDomainChrSourceDefParseXML)
(virDomainDiskSourceDefFormat, virDomainChrDefFormat)
(virDomainDiskDefFormat): Pass flags on through.
* src/security/security_selinux.c
(virSecuritySELinuxRestoreSecurityImageLabelInt): Honor labelskip
when possible.
(virSecuritySELinuxSetSecurityFileLabel): Set labelskip, not
norelabel, if labeling fails.
(virSecuritySELinuxSetFileconHelper): Fix indentation.
* docs/formatdomain.html.in (seclabel): Document new xml.
* docs/schemas/domaincommon.rng (devSeclabel): Allow it in RNG.
* tests/qemuxml2argvdata/qemuxml2argv-seclabel-*-labelskip.xml:
* tests/qemuxml2argvdata/qemuxml2argv-seclabel-*-labelskip.args:
* tests/qemuxml2xmloutdata/qemuxml2xmlout-seclabel-*-labelskip.xml:
New test files.
* tests/qemuxml2argvtest.c (mymain): Run the new tests.
* tests/qemuxml2xmltest.c (mymain): Likewise.

Signed-off-by: Eric Blake <eblake@redhat.com>
12 files changed:
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/security/security_selinux.c
tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-labelskip.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-labelskip.xml [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-seclabel-static-labelskip.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-seclabel-static-labelskip.xml [new file with mode: 0644]
tests/qemuxml2argvtest.c
tests/qemuxml2xmloutdata/qemuxml2xmlout-seclabel-dynamic-labelskip.xml [new file with mode: 0644]
tests/qemuxml2xmltest.c

index 12a756c2817573c9ec821733cfcf9e7e84a16738..ec011dd414ca9ed8b0e2f9a64b19340bfeb573b9 100644 (file)
@@ -5029,7 +5029,11 @@ qemu-kvm -net nic,model=? /dev/null
       a <code>seclabel</code> element is attached to a specific path
       rather than the top-level domain assignment, only the
       attribute <code>relabel</code> or the
-      sub-element <code>label</code> are supported.
+      sub-element <code>label</code> are supported.  Additionally,
+      <span class="since">since 1.1.2</span>, an output-only
+      element <code>labelskip</code> will be present for active
+      domains on disks where labeling was skipped due to the image
+      being on a file system that lacks security labeling.
     </p>
 
     <h2><a name="examples">Example configs</a></h2>
index ac807e6caf0f3ea67ef990937d9d048dd386e6c3..dfcd61cdd25aef86f6bb3b0dd320063e940e1d16 100644 (file)
   <define name="devSeclabel">
     <element name="seclabel">
       <!-- A per-device seclabel override is more limited, either
-           relabel=no or a <label> must be present.  -->
+           relabel=no or a <label> must be present on input;
+           output also can include labelskip=yes.  -->
+      <optional>
+        <attribute name='model'>
+          <text/>
+        </attribute>
+      </optional>
       <choice>
         <group>
-          <optional>
-            <attribute name='model'>
-              <text/>
-            </attribute>
-          </optional>
           <attribute name='relabel'>
             <value>no</value>
           </attribute>
         </group>
         <group>
-          <optional>
-            <attribute name='model'>
-              <text/>
-            </attribute>
-          </optional>
+          <attribute name='labelskip'>
+            <value>yes</value>
+          </attribute>
+        </group>
+        <group>
           <optional>
             <attribute name='relabel'>
               <value>yes</value>
             </attribute>
           </optional>
-          <zeroOrMore>
+          <oneOrMore>
             <element name='label'>
               <text/>
             </element>
-          </zeroOrMore>
+          </oneOrMore>
         </group>
       </choice>
     </element>
index 12b68eadf1fc109b8376d51adc4ee1f75ee9246f..ea49d2cda38af3ddde7fae8eaaa187cd77fd5d52 100644 (file)
@@ -4484,7 +4484,8 @@ static int
 virSecurityDeviceLabelDefParseXML(virSecurityDeviceLabelDefPtr **seclabels_rtn,
                                   size_t *nseclabels_rtn,
                                   virSecurityLabelDefPtr *vmSeclabels,
-                                  int nvmSeclabels, xmlXPathContextPtr ctxt)
+                                  int nvmSeclabels, xmlXPathContextPtr ctxt,
+                                  unsigned int flags)
 {
     virSecurityDeviceLabelDefPtr *seclabels;
     size_t nseclabels = 0;
@@ -4492,7 +4493,7 @@ virSecurityDeviceLabelDefParseXML(virSecurityDeviceLabelDefPtr **seclabels_rtn,
     size_t i, j;
     xmlNodePtr *list = NULL;
     virSecurityLabelDefPtr vmDef = NULL;
-    char *model, *relabel, *label;
+    char *model, *relabel, *label, *labelskip;
 
     if ((n = virXPathNodeSet("./seclabel", ctxt, &list)) < 0)
         goto error;
@@ -4547,6 +4548,13 @@ virSecurityDeviceLabelDefParseXML(virSecurityDeviceLabelDefPtr **seclabels_rtn,
             seclabels[i]->norelabel = false;
         }
 
+        /* labelskip is only parsed on live images */
+        labelskip = virXMLPropString(list[i], "labelskip");
+        seclabels[i]->labelskip = false;
+        if (labelskip && !(flags & VIR_DOMAIN_XML_INACTIVE))
+            seclabels[i]->labelskip = STREQ(labelskip, "yes");
+        VIR_FREE(labelskip);
+
         ctxt->node = list[i];
         label = virXPathStringLimit("string(./label)",
                                     VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
@@ -5208,7 +5216,8 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
                                               &def->nseclabels,
                                               vmSeclabels,
                                               nvmSeclabels,
-                                              ctxt) < 0)
+                                              ctxt,
+                                              flags) < 0)
             goto error;
         ctxt->node = saved_node;
     }
@@ -6884,7 +6893,8 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
                                                           &chr_def->nseclabels,
                                                           vmSeclabels,
                                                           nvmSeclabels,
-                                                          ctxt) < 0) {
+                                                          ctxt,
+                                                          flags) < 0) {
                         ctxt->node = saved_node;
                         goto error;
                     }
@@ -14018,14 +14028,23 @@ virSecurityLabelDefFormat(virBufferPtr buf, virSecurityLabelDefPtr def)
 
 static void
 virSecurityDeviceLabelDefFormat(virBufferPtr buf,
-                                virSecurityDeviceLabelDefPtr def)
+                                virSecurityDeviceLabelDefPtr def,
+                                unsigned int flags)
 {
+    /* For offline output, skip elements that allow labels but have no
+     * label specified (possible if labelskip was ignored on input).  */
+    if ((flags & VIR_DOMAIN_XML_INACTIVE) && !def->label && !def->norelabel)
+        return;
+
     virBufferAddLit(buf, "<seclabel");
 
     if (def->model)
         virBufferAsprintf(buf, " model='%s'", def->model);
 
-    virBufferAsprintf(buf, " relabel='%s'", def->norelabel ? "no" : "yes");
+    if (def->labelskip)
+        virBufferAddLit(buf, " labelskip='yes'");
+    else
+        virBufferAsprintf(buf, " relabel='%s'", def->norelabel ? "no" : "yes");
 
     if (def->label) {
         virBufferAddLit(buf, ">\n");
@@ -14100,7 +14119,8 @@ virDomainDiskBlockIoDefFormat(virBufferPtr buf,
 
 static int
 virDomainDiskSourceDefFormat(virBufferPtr buf,
-                             virDomainDiskDefPtr def)
+                             virDomainDiskDefPtr def,
+                             unsigned int flags)
 {
     int n;
     const char *startupPolicy = virDomainStartupPolicyTypeToString(def->startupPolicy);
@@ -14119,7 +14139,8 @@ virDomainDiskSourceDefFormat(virBufferPtr buf,
                 virBufferAddLit(buf, ">\n");
                 virBufferAdjustIndent(buf, 8);
                 for (n = 0; n < def->nseclabels; n++)
-                    virSecurityDeviceLabelDefFormat(buf, def->seclabels[n]);
+                    virSecurityDeviceLabelDefFormat(buf, def->seclabels[n],
+                                                    flags);
                 virBufferAdjustIndent(buf, -8);
                 virBufferAddLit(buf, "      </source>\n");
             } else {
@@ -14136,7 +14157,8 @@ virDomainDiskSourceDefFormat(virBufferPtr buf,
                 virBufferAddLit(buf, ">\n");
                 virBufferAdjustIndent(buf, 8);
                 for (n = 0; n < def->nseclabels; n++)
-                    virSecurityDeviceLabelDefFormat(buf, def->seclabels[n]);
+                    virSecurityDeviceLabelDefFormat(buf, def->seclabels[n],
+                                                    flags);
                 virBufferAdjustIndent(buf, -8);
                 virBufferAddLit(buf, "      </source>\n");
             } else {
@@ -14201,7 +14223,8 @@ virDomainDiskSourceDefFormat(virBufferPtr buf,
                 virBufferAddLit(buf, ">\n");
                 virBufferAdjustIndent(buf, 8);
                 for (n = 0; n < def->nseclabels; n++)
-                    virSecurityDeviceLabelDefFormat(buf, def->seclabels[n]);
+                    virSecurityDeviceLabelDefFormat(buf, def->seclabels[n],
+                                                    flags);
                 virBufferAdjustIndent(buf, -8);
                 virBufferAddLit(buf, "      </source>\n");
             } else {
@@ -14337,7 +14360,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
         virBufferAddLit(buf, "      </auth>\n");
     }
 
-    if (virDomainDiskSourceDefFormat(buf, def) < 0)
+    if (virDomainDiskSourceDefFormat(buf, def, flags) < 0)
         return -1;
     virDomainDiskGeometryDefFormat(buf, def);
     virDomainDiskBlockIoDefFormat(buf, def);
@@ -15189,7 +15212,7 @@ virDomainChrDefFormat(virBufferPtr buf,
     if (def->seclabels && def->nseclabels > 0) {
         virBufferAdjustIndent(buf, 2);
         for (n = 0; n < def->nseclabels; n++)
-            virSecurityDeviceLabelDefFormat(buf, def->seclabels[n]);
+            virSecurityDeviceLabelDefFormat(buf, def->seclabels[n], flags);
         virBufferAdjustIndent(buf, -2);
     }
 
index 3e118d63d36bd068f2e714755d8af8d93e646849..500a5be9d86149d42b02491a13f48c17b42af7b9 100644 (file)
@@ -343,7 +343,8 @@ typedef virSecurityDeviceLabelDef *virSecurityDeviceLabelDefPtr;
 struct _virSecurityDeviceLabelDef {
     char *model;
     char *label;        /* image label string */
-    bool norelabel;
+    bool norelabel;     /* true to skip label attempts */
+    bool labelskip;     /* live-only; true if skipping failed label attempt */
 };
 
 
index e3dce66a2d7cb1787046e9ae82f431cf8c5ec541..38de06076b017441c36698041d0d0bcdcd609181 100644 (file)
@@ -917,10 +917,10 @@ virSecuritySELinuxSetFileconHelper(const char *path, char *tcon, bool optional)
                 security_get_boolean_active("virt_use_nfs") != 1) {
                 msg = _("Setting security context '%s' on '%s' not supported. "
                         "Consider setting virt_use_nfs");
-               if (security_getenforce() == 1)
-                   VIR_WARN(msg, tcon, path);
-               else
-                   VIR_INFO(msg, tcon, path);
+                if (security_getenforce() == 1)
+                    VIR_WARN(msg, tcon, path);
+                else
+                    VIR_INFO(msg, tcon, path);
             } else {
                 VIR_INFO("Setting security context '%s' on '%s' not supported",
                          tcon, path);
@@ -1135,6 +1135,14 @@ virSecuritySELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
     if (seclabel->norelabel || (disk_seclabel && disk_seclabel->norelabel))
         return 0;
 
+    /* If labelskip is true and there are no backing files, then we
+     * know it is safe to skip the restore.  FIXME - backing files should
+     * be tracked in domain XML, at which point labelskip should be a
+     * per-file attribute instead of a disk attribute.  */
+    if (disk_seclabel && disk_seclabel->labelskip &&
+        !disk->backingChain)
+        return 0;
+
     /* Don't restore labels on readoly/shared disks, because
      * other VMs may still be accessing these
      * Alternatively we could iterate over all running
@@ -1219,7 +1227,7 @@ virSecuritySELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
         disk_seclabel = virDomainDiskDefGenSecurityLabelDef(SECURITY_SELINUX_NAME);
         if (!disk_seclabel)
             return -1;
-        disk_seclabel->norelabel = true;
+        disk_seclabel->labelskip = true;
         if (VIR_APPEND_ELEMENT(disk->seclabels, disk->nseclabels,
                                disk_seclabel) < 0) {
             virSecurityDeviceLabelDefFree(disk_seclabel);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-labelskip.args b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-labelskip.args
new file mode 100644 (file)
index 0000000..892c6b5
--- /dev/null
@@ -0,0 +1,5 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu \
+-name QEMUGuest1 -S -M pc -m 214 -smp 1 -nographic -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \
+-hda /dev/HostVG/QEMUGuest1 \
+-net none -serial none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-labelskip.xml b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-dynamic-labelskip.xml
new file mode 100644 (file)
index 0000000..e3bc700
--- /dev/null
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static' cpuset='1-4,8-20,525'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'>
+        <seclabel model='selinux' labelskip='yes'/>
+      </source>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <memballoon model='virtio'/>
+  </devices>
+  <seclabel type='dynamic' model='selinux' relabel='yes'>
+    <baselabel>system_u:system_r:svirt_custom_t:s0</baselabel>
+  </seclabel>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-static-labelskip.args b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-static-labelskip.args
new file mode 100644 (file)
index 0000000..892c6b5
--- /dev/null
@@ -0,0 +1,5 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu \
+-name QEMUGuest1 -S -M pc -m 214 -smp 1 -nographic -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \
+-hda /dev/HostVG/QEMUGuest1 \
+-net none -serial none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-static-labelskip.xml b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-static-labelskip.xml
new file mode 100644 (file)
index 0000000..a743448
--- /dev/null
@@ -0,0 +1,33 @@
+<domain type='qemu' id='1'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static' cpuset='1-4,8-20,525'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'>
+        <seclabel model='selinux' labelskip='yes'/>
+      </source>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <memballoon model='virtio'/>
+  </devices>
+  <seclabel type='static' model='selinux' relabel='yes'>
+    <label>system_u:system_r:svirt_custom_t:s0:c192,c392</label>
+    <imagelabel>system_u:system_r:svirt_custom_t:s0:c192,c392</imagelabel>
+  </seclabel>
+</domain>
index 679124e35b52dc754a837dec72a71cf131ad2346..3a3c30415773dc532e388bdb57aab96a3ba38aba 100644 (file)
@@ -923,8 +923,10 @@ mymain(void)
     DO_TEST("seclabel-dynamic", QEMU_CAPS_NAME);
     DO_TEST("seclabel-dynamic-baselabel", QEMU_CAPS_NAME);
     DO_TEST("seclabel-dynamic-override", QEMU_CAPS_NAME);
+    DO_TEST("seclabel-dynamic-labelskip", QEMU_CAPS_NAME);
     DO_TEST("seclabel-static", QEMU_CAPS_NAME);
     DO_TEST("seclabel-static-relabel", QEMU_CAPS_NAME);
+    DO_TEST("seclabel-static-labelskip", QEMU_CAPS_NAME);
     DO_TEST("seclabel-none", QEMU_CAPS_NAME);
 
     DO_TEST("pseries-basic",
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-seclabel-dynamic-labelskip.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-seclabel-dynamic-labelskip.xml
new file mode 100644 (file)
index 0000000..0764691
--- /dev/null
@@ -0,0 +1,31 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static' cpuset='1-4,8-20,525'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'>
+      </source>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <memballoon model='virtio'/>
+  </devices>
+  <seclabel type='dynamic' model='selinux' relabel='yes'>
+    <baselabel>system_u:system_r:svirt_custom_t:s0</baselabel>
+  </seclabel>
+</domain>
index 5c6730d25ebc54e0dd5cbc4b8f87d106f0646e7f..6eebc685f9d4ce1904afd786f1e9ad01746a10bb 100644 (file)
@@ -30,6 +30,7 @@ testCompareXMLToXMLFiles(const char *inxml, const char *outxml, bool live)
     char *actual = NULL;
     int ret = -1;
     virDomainDefPtr def = NULL;
+    unsigned int flags = live ? 0 : VIR_DOMAIN_XML_INACTIVE;
 
     if (virtTestLoadFile(inxml, &inXmlData) < 0)
         goto fail;
@@ -37,11 +38,10 @@ testCompareXMLToXMLFiles(const char *inxml, const char *outxml, bool live)
         goto fail;
 
     if (!(def = virDomainDefParseString(inXmlData, driver.caps, driver.xmlopt,
-                                        QEMU_EXPECTED_VIRT_TYPES,
-                                        live ? 0 : VIR_DOMAIN_XML_INACTIVE)))
+                                        QEMU_EXPECTED_VIRT_TYPES, flags)))
         goto fail;
 
-    if (!(actual = virDomainDefFormat(def, VIR_DOMAIN_XML_SECURE)))
+    if (!(actual = virDomainDefFormat(def, VIR_DOMAIN_XML_SECURE | flags)))
         goto fail;
 
     if (STRNEQ(outXmlData, actual)) {
@@ -257,7 +257,9 @@ mymain(void)
 
     DO_TEST_FULL("seclabel-dynamic-baselabel", false, WHEN_INACTIVE);
     DO_TEST_FULL("seclabel-dynamic-override", false, WHEN_INACTIVE);
+    DO_TEST_FULL("seclabel-dynamic-labelskip", true, WHEN_INACTIVE);
     DO_TEST("seclabel-static");
+    DO_TEST_FULL("seclabel-static-labelskip", false, WHEN_ACTIVE);
     DO_TEST("seclabel-none");
     DO_TEST("numad-static-vcpu-no-numatune");
     DO_TEST("disk-scsi-lun-passthrough-sgio");