[PATCH] qemu: migration: Ensure that compression program error buffer is in scope during runtime
From: Peter Krempa <pkrempa@redhat.com> 'virCommand' requires that the error buffer is available while the process is running. In 'qemuMigrationSrcToLegacyFile' a stack'd variable for the buffer pointer is registered, and the command is started, but it may continue executing even after return to the caller 'qemuMigrationSrcToFile' where 'virCommandWait' is called and thus if the command generates stderr after that it can overwrite the stack variable. This happens since the function was split into multiple parts in c2518f7bc7dd4f8ab8655a12ec3a000e1eb5b232. Fix it by moving the error buffer to 'qemuMigrationSrcToFile'. It's used for a debug message so we can move it up. Fixes: c2518f7bc7dd4f8ab8655a12ec3a000e1eb5b232 Closes: https://gitlab.com/libvirt/libvirt/-/work_items/932 Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_migration.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 76661de09a..5d4d8b5a32 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -7225,7 +7225,6 @@ qemuMigrationSrcToLegacyFile(virDomainObj *vm, qemuDomainObjPrivate *priv = vm->privateData; int ret = -1; int pipeFD[2] = { -1, -1 }; - char *errbuf = NULL; if (compressor && virPipe(pipeFD) < 0) return -1; @@ -7246,7 +7245,6 @@ qemuMigrationSrcToLegacyFile(virDomainObj *vm, } else { virCommandSetInputFD(compressor, pipeFD[0]); virCommandSetOutputFD(compressor, &fd); - virCommandSetErrorBuffer(compressor, &errbuf); virCommandDoAsyncIO(compressor); if (virSetCloseExec(pipeFD[1]) < 0) { virReportSystemError(errno, "%s", @@ -7269,11 +7267,6 @@ qemuMigrationSrcToLegacyFile(virDomainObj *vm, VIR_FORCE_CLOSE(pipeFD[0]); VIR_FORCE_CLOSE(pipeFD[1]); - if (errbuf) { - VIR_DEBUG("Compression binary stderr: %s", NULLSTR(errbuf)); - VIR_FREE(errbuf); - } - return ret; } @@ -7342,6 +7335,7 @@ qemuMigrationSrcToFile(virDomainObj *vm, int ret = -1; unsigned long saveMigBandwidth = priv->migMaxBandwidth; virErrorPtr orig_err = NULL; + g_autofree char *compressor_errbuf = NULL; if (qemuMigrationSetDBusVMState(vm) < 0) return -1; @@ -7367,10 +7361,12 @@ qemuMigrationSrcToFile(virDomainObj *vm, } if (migParams && - qemuMigrationParamsCapEnabled(migParams, QEMU_MIGRATION_CAP_MAPPED_RAM)) + qemuMigrationParamsCapEnabled(migParams, QEMU_MIGRATION_CAP_MAPPED_RAM)) { rc = qemuMigrationSrcToSparseFile(vm, path, fd, bypassCache, asyncJob); - else + } else { + virCommandSetErrorBuffer(compressor, &compressor_errbuf); rc = qemuMigrationSrcToLegacyFile(vm, *fd, compressor, asyncJob); + } if (rc < 0) goto cleanup; @@ -7397,6 +7393,9 @@ qemuMigrationSrcToFile(virDomainObj *vm, if (ret < 0 && !orig_err) virErrorPreserveLast(&orig_err); + if (compressor_errbuf) + VIR_DEBUG("Compression binary stderr: %s", compressor_errbuf); + /* Remove fdset passed to qemu and restore max migration bandwidth */ if (qemuDomainObjIsActive(vm)) { if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) == 0) { -- 2.56.0
On Thu, Nov 05, 2026 at 11:53:36 +0100, Peter Krempa wrote:
From: Peter Krempa <pkrempa@redhat.com>
'virCommand' requires that the error buffer is available while the process is running.
In 'qemuMigrationSrcToLegacyFile' a stack'd variable for the buffer pointer is registered, and the command is started, but it may continue executing even after return to the caller 'qemuMigrationSrcToFile' where 'virCommandWait' is called and thus if the command generates stderr after that it can overwrite the stack variable.
This happens since the function was split into multiple parts in c2518f7bc7dd4f8ab8655a12ec3a000e1eb5b232.
Fix it by moving the error buffer to 'qemuMigrationSrcToFile'. It's used for a debug message so we can move it up.
Fixes: c2518f7bc7dd4f8ab8655a12ec3a000e1eb5b232 Closes: https://gitlab.com/libvirt/libvirt/-/work_items/932 Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_migration.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
participants (2)
-
Jiri Denemark -
Peter Krempa