[libvirt] [PATCH] qemu: Avoid using ".(null)" in UNIX socket path

The code which generates paths for UNIX socket blindly used target name without checking if it was set. Thus for the following device XML <channel type='unix'> <source mode='bind'/> <target type='virtio'/> </channel> we would generate "/var/lib/libvirt/qemu/channel/target/NAME.(null)" path which works but is not really correct. Let's not use the ".target_name" suffix at all if target name is not set. https://bugzilla.redhat.com/show_bug.cgi?id=1226854 Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 20 +++++++++--- .../qemuxml2argv-channel-virtio-unix.args | 19 +++++++++++ .../qemuxml2argv-channel-virtio-unix.xml | 37 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 5 +++ 4 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.xml diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 6213fd9..404489c 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1249,11 +1249,23 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, dev->data.chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL && dev->data.chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO && dev->data.chr->source.type == VIR_DOMAIN_CHR_TYPE_UNIX && - !dev->data.chr->source.data.nix.path && cfg) { - if (virAsprintf(&dev->data.chr->source.data.nix.path, "%s/%s.%s", - cfg->channelTargetDir, - def->name, dev->data.chr->target.name) < 0) + !dev->data.chr->source.data.nix.path) { + if (!cfg) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("cannot generate UNIX socket path")); goto cleanup; + } + + if (dev->data.chr->target.name) { + if (virAsprintf(&dev->data.chr->source.data.nix.path, "%s/%s.%s", + cfg->channelTargetDir, + def->name, dev->data.chr->target.name) < 0) + goto cleanup; + } else { + if (virAsprintf(&dev->data.chr->source.data.nix.path, "%s/%s", + cfg->channelTargetDir, def->name) < 0) + goto cleanup; + } dev->data.chr->source.data.nix.listen = true; } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args new file mode 100644 index 0000000..43a34ce --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args @@ -0,0 +1,19 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-device virtio-serial-pci,id=virtio-serial1,bus=pci.0,addr=0xa \ +-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x3 \ +-usb \ +-hda /dev/HostVG/QEMUGuest1 \ +-chardev socket,id=charchannel0,path=\ +/tmp/QEMUGuest1.org.qemu.guest_agent.0,server,nowait \ +-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,\ +name=org.qemu.guest_agent.0 \ +-chardev socket,id=charchannel1,path=/tmp/QEMUGuest1,server,nowait \ +-device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1 \ +-chardev socket,id=charchannel2,path=/tmp/QEMUGuest1.ble,server,nowait \ +-device virtserialport,bus=virtio-serial0.0,nr=3,chardev=charchannel2,id=channel2,\ +name=ble diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.xml b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.xml new file mode 100644 index 0000000..7fac943 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.xml @@ -0,0 +1,37 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219136</memory> + <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'/> + <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='virtio-serial' index='1'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> + </controller> + <channel type='unix'> + <target type='virtio' name='org.qemu.guest_agent.0'/> + </channel> + <channel type='unix'> + <target type='virtio'/> + </channel> + <channel type='unix'> + <target type='virtio' name='ble'/> + </channel> + <memballoon model='none'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 4154601..6f8332d 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -519,6 +519,9 @@ mymain(void) driver.config->spiceTLS = 1; if (VIR_STRDUP_QUIET(driver.config->spicePassword, "123456") < 0) return EXIT_FAILURE; + VIR_FREE(driver.config->channelTargetDir); + if (VIR_STRDUP_QUIET(driver.config->channelTargetDir, "/tmp") < 0) + return EXIT_FAILURE; # define DO_TEST_FULL(name, migrateFrom, migrateFd, flags, ...) \ do { \ @@ -1113,6 +1116,8 @@ mymain(void) DO_TEST("channel-virtio-default", QEMU_CAPS_DEVICE, QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_SPICE, QEMU_CAPS_CHARDEV_SPICEVMC); + DO_TEST("channel-virtio-unix", + QEMU_CAPS_DEVICE, QEMU_CAPS_CHARDEV, QEMU_CAPS_NODEFCONFIG); DO_TEST("smartcard-host", QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, -- 2.4.5

On 30.06.2015 13:49, Jiri Denemark wrote:
The code which generates paths for UNIX socket blindly used target name without checking if it was set. Thus for the following device XML
<channel type='unix'> <source mode='bind'/> <target type='virtio'/> </channel>
we would generate "/var/lib/libvirt/qemu/channel/target/NAME.(null)" path which works but is not really correct. Let's not use the ".target_name" suffix at all if target name is not set.
https://bugzilla.redhat.com/show_bug.cgi?id=1226854
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 20 +++++++++--- .../qemuxml2argv-channel-virtio-unix.args | 19 +++++++++++ .../qemuxml2argv-channel-virtio-unix.xml | 37 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 5 +++ 4 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.xml
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 6213fd9..404489c 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1249,11 +1249,23 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, dev->data.chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL && dev->data.chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO && dev->data.chr->source.type == VIR_DOMAIN_CHR_TYPE_UNIX && - !dev->data.chr->source.data.nix.path && cfg) { - if (virAsprintf(&dev->data.chr->source.data.nix.path, "%s/%s.%s", - cfg->channelTargetDir, - def->name, dev->data.chr->target.name) < 0) + !dev->data.chr->source.data.nix.path) { + if (!cfg) {
Can this ever happen or you just want to be super-trouper future proof?
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("cannot generate UNIX socket path")); goto cleanup; + } + + if (dev->data.chr->target.name) { + if (virAsprintf(&dev->data.chr->source.data.nix.path, "%s/%s.%s", + cfg->channelTargetDir, + def->name, dev->data.chr->target.name) < 0) + goto cleanup; + } else { + if (virAsprintf(&dev->data.chr->source.data.nix.path, "%s/%s", + cfg->channelTargetDir, def->name) < 0) + goto cleanup; + }
dev->data.chr->source.data.nix.listen = true; }
ACK and safe for the freeze. Micha

On Tue, Jun 30, 2015 at 16:04:23 +0200, Michal Privoznik wrote:
On 30.06.2015 13:49, Jiri Denemark wrote:
The code which generates paths for UNIX socket blindly used target name without checking if it was set. Thus for the following device XML
<channel type='unix'> <source mode='bind'/> <target type='virtio'/> </channel>
we would generate "/var/lib/libvirt/qemu/channel/target/NAME.(null)" path which works but is not really correct. Let's not use the ".target_name" suffix at all if target name is not set.
https://bugzilla.redhat.com/show_bug.cgi?id=1226854
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_domain.c | 20 +++++++++--- .../qemuxml2argv-channel-virtio-unix.args | 19 +++++++++++ .../qemuxml2argv-channel-virtio-unix.xml | 37 ++++++++++++++++++++++ tests/qemuxml2argvtest.c | 5 +++ 4 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.xml
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 6213fd9..404489c 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1249,11 +1249,23 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, dev->data.chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL && dev->data.chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO && dev->data.chr->source.type == VIR_DOMAIN_CHR_TYPE_UNIX && - !dev->data.chr->source.data.nix.path && cfg) { - if (virAsprintf(&dev->data.chr->source.data.nix.path, "%s/%s.%s", - cfg->channelTargetDir, - def->name, dev->data.chr->target.name) < 0) + !dev->data.chr->source.data.nix.path) { + if (!cfg) {
Can this ever happen or you just want to be super-trouper future proof?
I think it shouldn't happen but the check for cfg was there before and it is also used in several other places so I didn't really feel like changing it within this patch.
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("cannot generate UNIX socket path")); goto cleanup; + } + + if (dev->data.chr->target.name) { + if (virAsprintf(&dev->data.chr->source.data.nix.path, "%s/%s.%s", + cfg->channelTargetDir, + def->name, dev->data.chr->target.name) < 0) + goto cleanup; + } else { + if (virAsprintf(&dev->data.chr->source.data.nix.path, "%s/%s", + cfg->channelTargetDir, def->name) < 0) + goto cleanup; + }
dev->data.chr->source.data.nix.listen = true; }
ACK and safe for the freeze.
Micha
Thanks and pushed, Jirk
participants (2)
-
Jiri Denemark
-
Michal Privoznik