There is one specific caller (testInfoSetArgs() in
qemuxml2argvtest.c) which expect the va_list argument to change
after returning from the virQEMUCapsSetVAList() function.
However, since we are passing plain va_list this is not
guaranteed. The man page of stdarg(3) says:
If ap is passed to a function that uses va_arg(ap,type), then
the value of ap is undefined after the return of that function.
(ap is a variable of type va_list)
I've seen this in action in fact: on i686 the qemuxml2argvtest
fails on the second test case because testInfoSetArgs() sees
ARG_QEMU_CAPS and callse virQEMUCapsSetVAList to process the
capabilities (in this case there's just one
QEMU_CAPS_SECCOMP_BLACKLIST). But since the changes are not
reflected in the caller, in the next iteration testInfoSetArgs()
sees the qemu capability and not ARG_END.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
This passed successfully on x86_64 and i686 in my testing.
src/qemu/qemu_capabilities.c | 6 +++---
src/qemu/qemu_capabilities.h | 2 +-
tests/qemuxml2argvtest.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index c5954edaf0..e182a2c2e5 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1665,11 +1665,11 @@ virQEMUCapsSet(virQEMUCapsPtr qemuCaps,
void
virQEMUCapsSetVAList(virQEMUCapsPtr qemuCaps,
- va_list list)
+ va_list *list)
{
int flag;
- while ((flag = va_arg(list, int)) < QEMU_CAPS_LAST)
+ while ((flag = va_arg(*list, int)) < QEMU_CAPS_LAST)
ignore_value(virBitmapSetBit(qemuCaps->flags, flag));
}
@@ -1680,7 +1680,7 @@ virQEMUCapsSetList(virQEMUCapsPtr qemuCaps, ...)
va_list list;
va_start(list, qemuCaps);
- virQEMUCapsSetVAList(qemuCaps, list);
+ virQEMUCapsSetVAList(qemuCaps, &list);
va_end(list);
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 7625d754a3..ceab8c9154 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -519,7 +519,7 @@ void virQEMUCapsSet(virQEMUCapsPtr qemuCaps,
virQEMUCapsFlags flag) ATTRIBUTE_NONNULL(1);
void virQEMUCapsSetVAList(virQEMUCapsPtr qemuCaps,
- va_list list) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+ va_list *list) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
void virQEMUCapsSetList(virQEMUCapsPtr qemuCaps, ...) ATTRIBUTE_NONNULL(1);
void virQEMUCapsClear(virQEMUCapsPtr qemuCaps,
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 6e7d1b0b9a..a7a8d77e1d 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -650,7 +650,7 @@ testInfoSetArgs(struct testInfo *info,
case ARG_QEMU_CAPS:
if (qemuCaps || !(qemuCaps = virQEMUCapsNew()))
goto cleanup;
- virQEMUCapsSetVAList(qemuCaps, argptr);
+ virQEMUCapsSetVAList(qemuCaps, &argptr);
break;
case ARG_GIC:
--
2.19.2