In GLib, GByteArray is an object managed by the library. Currently,
migrating a GByteArray requires treating it as a raw C struct and using
VMSTATE_VBUFFER_ALLOC_UINT32. For example, see vmstate_vdba in
ui/vdagent.c
QEMU cannot pretend that GByteArray is a C struct and simply use
VMS_ALLOC to g_malloc() the buffer. This is because, VMS_ALLOC blindly
overwrites the data pointer with a newly allocated buffer, thereby
leaking the previous memory. Besides, GLib tracks the array's capacity
in a hidden alloc field. Bypassing GLib APIs leave this capacity out of
sync with the newly allocated buffer, potentially leading to heap buffer
overflows during subsequent g_byte_array_append() calls.
This series adds a new VMState called VMSTATE_GBYTEARRAY, which will
directly use GLib library API calls to create, or resize the object.
This is then used in ui/vdaagent.c replacing the use of
VMSTATE_VBUFFER_ALLOC_UINT32.
Changes in v2:
- Marc-André pointed out the problem of not updating the device state
itself. To do that we should essentially pass a pointer to the
GByteArray pointer. Remove VMS_POINTER from VMSTATE_GBYTEARRAY. This
changes 'pv' to be the address of the pointer field (GByteArray **)
instead of the pointer's value.
- Update get_g_byte_array and put_g_byte_array to handle this additional
level of indirection, allowing safe allocation and updating device state.
- Link to v1: https://lore.kernel.org/all/20260406115247.4879-1-armenon@redhat.com/
Arun Menon (2):
migration/vmstate: Add VMState support for GByteArray
ui/vdagent: Use VMSTATE_GBYTEARRAY to safely migrate outbuf
include/migration/vmstate.h | 10 ++++++++++
migration/vmstate-types.c | 37 +++++++++++++++++++++++++++++++++++++
ui/vdagent.c | 13 +------------
3 files changed, 48 insertions(+), 12 deletions(-)
--
2.53.0