@samitouri / QOSamiQemu / commits / c3b99f3091

migration: Harden vmstate_handle_alloc

Harden the vmstate_handle_alloc function against overflow of the 64bit integers it consumes and failure to allocate due to an exceedingly large request. Acked-by: Peter Xu <peterx@redhat.com> Signed-off-by: Fabiano Rosas <farosas@suse.de>

Fabiano Rosas committed Aug 18, 2026 at 15:24 UTC c3b99f3091d0c840c33fc204c8dacdb599abc83d
1 file changed +22 -8
migration/vmstate.c
+22 -8
@@ -148,16 +148,28 @@ static uint64_t vmstate_size(void *opaque, const VMStateField *field)
148 return size;
149 }
150
151 -static void vmstate_handle_alloc(void *ptr, const VMStateField *field,
152 - void *opaque)
151 +static bool vmstate_handle_alloc(void *ptr, const VMStateField *field,
152 + uint64_t n, uint64_t size, Error **errp)
153 {
154 + void *p;
155 +
156 if (field->flags & VMS_POINTER && field->flags & VMS_ALLOC) {
155 - uint64_t size = vmstate_size(opaque, field);
156 - size *= vmstate_n_elems(opaque, field);
157 - if (size) {
158 - *(void **)ptr = g_malloc(size);
159 - }
157 + if (size && n) {
158 + if (umul64_overflow(size, n, &size)) {
159 + error_setg(errp, "%s: field '%s' multiply overflow",
160 + __func__, field->name);
161 + return false;
162 + }
163 + p = g_try_malloc(size);
164 + if (!p) {
165 + error_setg(errp, "%s: Could not allocate memory for field '%s'",
166 + __func__, field->name);
167 + return false;
168 + }
169 + *(void **)ptr = p;
170 + }
171 }
172 + return true;
173 }
174
175 static bool vmstate_ptr_marker_load(QEMUFile *f, bool *load_field,
@@ -367,7 +379,9 @@ bool vmstate_load_vmsd(QEMUFile *f, const VMStateDescription *vmsd,
379 uint64_t n_elems = vmstate_n_elems(opaque, field);
380 uint64_t size = vmstate_size(opaque, field);
381
370 - vmstate_handle_alloc(first_elem, field, opaque);
382 + if (!vmstate_handle_alloc(first_elem, field, n_elems, size, errp)) {
383 + return false;
384 + }
385 if (field->flags & VMS_POINTER) {
386 first_elem = *(void **)first_elem;
387 assert(first_elem || !n_elems || !size);