From 8f95ef95d62234b7147e068afdfd27cdd2ac7535 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Thu, 22 Dec 2022 10:25:38 +0100 Subject: [PATCH] virQEMUDriverGetDomainCapabilities: Validate arguments When calling virConnectGetDomainCapabilities() (exposed as virsh domcapabilities) users have option to specify whatever sub-set of { emulatorbin, arch, machine, virttype } they want. Then we have a logic (hidden in virQEMUCapsCacheLookupDefault()) that picks qemuCaps that satisfy values passed by user. And whatever was not specified is then set to the default value as specified by picked qemuCaps. For instance: if no machine type was provided but emulatorbin was, then the machine type is set to the default one as defined by the emulatorbin. Or, when just virttype was set then the remaining three values are set to their respective defaults. Except, we have a crasher in this case: # virsh domcapabilities --virttype hvf error: Disconnected from qemu:///system due to end of file error: failed to get emulator capabilities error: End of file while reading data: Input/output error This is because for 'hvf' virttype (at least my) QEMU does not have any machine type. Therefore, @machine is set to NULL and the rest of the code does not expect that. What we can do about this is to validate all arguments. Well, except for the emulatorbin which is obtained from passed qemuCaps. This also fixes the issue when domcapabilities for a virttype of a different driver are requested, or a different arch. Signed-off-by: Michal Privoznik Reviewed-by: Martin Kletzander --- src/qemu/qemu_conf.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index ae5bbcd138..6760bef14c 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1454,6 +1454,27 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriver *driver, g_autoptr(virDomainCaps) domCaps = NULL; const char *path = virQEMUCapsGetBinary(qemuCaps); + if (!virQEMUCapsIsArchSupported(qemuCaps, arch)) { + virReportError(VIR_ERR_INVALID_ARG, + _("Emulator '%s' does not support arch '%s'"), + path, virArchToString(arch)); + return NULL; + } + + if (!virQEMUCapsIsVirtTypeSupported(qemuCaps, virttype)) { + virReportError(VIR_ERR_INVALID_ARG, + _("Emulator '%s' does not support virt type '%s'"), + path, virDomainVirtTypeToString(virttype)); + return NULL; + } + + if (!virQEMUCapsIsMachineSupported(qemuCaps, virttype, machine)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Emulator '%s' does not support machine type '%s'"), + path, NULLSTR(machine)); + return NULL; + } + if (!(domCaps = virDomainCapsNew(path, machine, arch, virttype))) return NULL;