https://bugzilla.redhat.com/show_bug.cgi?id=1066894 With current code it's possible to have for instance: virsh dumpxml mydomain | grep seclabel <seclabel type='dynamic' model='selinux' relabel='yes'/> <seclabel type='dynamic' model='selinux' relabel='yes'/> <seclabel type='dynamic' model='selinux' relabel='yes'/> <seclabel type='dynamic' model='selinux' relabel='yes'/> <seclabel type='dynamic' model='selinux' relabel='yes'/> what doesn't make any sense. We should reject the XML in the config parsing phase. Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- src/conf/domain_conf.c | 18 ++++++++-- .../qemuxml2argv-seclabel-multiple.xml | 40 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-seclabel-multiple.xml diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c730d37..ace3ddf 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4668,7 +4668,7 @@ virSecurityLabelDefsParseXML(virDomainDefPtr def, virCapsPtr caps, unsigned int flags) { - size_t i = 0; + size_t i = 0, j; int n; xmlNodePtr *list = NULL, saved_node; virCapsHostPtr host = &caps->host; @@ -4689,10 +4689,22 @@ virSecurityLabelDefsParseXML(virDomainDefPtr def, /* Parse each "seclabel" tag */ for (i = 0; i < n; i++) { + virSecurityLabelDefPtr seclabel; + ctxt->node = list[i]; - def->seclabels[i] = virSecurityLabelDefParseXML(ctxt, flags); - if (def->seclabels[i] == NULL) + if (!(seclabel = virSecurityLabelDefParseXML(ctxt, flags))) goto error; + + for (j = 0; j < i; j++) { + if (STREQ_NULLABLE(seclabel->model, def->seclabels[j]->model)) { + virReportError(VIR_ERR_XML_DETAIL, + _("seclablel for model %s is already provided"), + seclabel->model); + goto error; + } + } + + def->seclabels[i] = seclabel; } def->nseclabels = n; ctxt->node = saved_node; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-seclabel-multiple.xml b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-multiple.xml new file mode 100644 index 0000000..bd6fd15 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-seclabel-multiple.xml @@ -0,0 +1,40 @@ +<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> + <backingStore/> + <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='none' relabel='no'/> + <seclabel type='dynamic' model='dac' relabel='yes'/> + <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> + <seclabel type='static' model='selinux' relabel='yes'> + <label>system_u:system_r:svirt_custom_t:s0:c192,c393</label> + <imagelabel>system_u:system_r:svirt_custom_t:s0:c192,c393</imagelabel> + </seclabel> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index bbc0fb7..a841adb 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1223,6 +1223,7 @@ mymain(void) DO_TEST("seclabel-static-labelskip", QEMU_CAPS_NAME); DO_TEST("seclabel-none", QEMU_CAPS_NAME); DO_TEST("seclabel-dac-none", QEMU_CAPS_NAME); + DO_TEST_PARSE_ERROR("seclabel-multiple", QEMU_CAPS_NAME); DO_TEST("pseries-basic", QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); -- 1.8.5.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list