@samitouri / QOSamiQemu / commits / cf45083edc

migration/multifd: Replace assert() with error_setg() in recv paths

QPL and UADK multifd backends use assert() to validate wire-controlled fields like per-page compressed lengths and packet size consistency. These asserts will stop working with -DNDEBUG builds, so may stop working. Replace all assert() calls in the receive path with proper error_setg() so validation failures are reported gracefully rather than crashing or silently ignored. While at it, touch up an assert() in qatzip recv path too. Cc: qemu-stable <qemu-stable@nongnu.org> Cc: Yuan Liu <yuan1.liu@intel.com> Cc: Yichen Wang <yichen.wang@bytedance.com> Reviewed-by: Fabiano Rosas <farosas@suse.de> Link: https://lore.kernel.org/r/20260728210417.1925078-4-peterx@redhat.com Signed-off-by: Peter Xu <peterx@redhat.com>

Peter Xu committed Jul 28, 2026 at 17:04 UTC cf45083edc2b760a952836187aba7ec4139418c0
3 files changed +44 -9
migration/multifd-qatzip.c
+4 -1
@@ -348,7 +348,10 @@ static int qatzip_recv(MultiFDRecvParams *p, Error **errp)
348
349 multifd_recv_zero_page_process(p);
350 if (!p->normal_num) {
351 - assert(in_size == 0);
351 + if (in_size != 0) {
352 + error_setg(errp, "multifd %u: expected empty packet", p->id);
353 + return -1;
354 + }
355 return 0;
356 }
357
migration/multifd-qpl.c
+20 -4
@@ -664,26 +664,42 @@ static int multifd_qpl_recv(MultiFDRecvParams *p, Error **errp)
664 }
665 multifd_recv_zero_page_process(p);
666 if (!p->normal_num) {
667 - assert(in_size == 0);
667 + if (in_size != 0) {
668 + error_setg(errp, "multifd %u: expected empty packet", p->id);
669 + return -1;
670 + }
671 return 0;
672 }
673
674 /* read compressed page lengths */
675 len = p->normal_num * sizeof(uint32_t);
673 - assert(len < in_size);
676 + if (len >= in_size) {
677 + error_setg(errp, "multifd %u: header len %"PRIu32
678 + " >= packet size %"PRIu32, p->id, len, in_size);
679 + return -1;
680 + }
681 ret = qio_channel_read_all(p->c, (void *) qpl->zlen, len, errp);
682 if (ret != 0) {
683 return ret;
684 }
685 for (int i = 0; i < p->normal_num; i++) {
686 qpl->zlen[i] = be32_to_cpu(qpl->zlen[i]);
680 - assert(qpl->zlen[i] <= multifd_ram_page_size());
687 + if (qpl->zlen[i] > multifd_ram_page_size()) {
688 + error_setg(errp, "multifd %u: page %d compressed len %"
689 + PRIu32" too large", p->id, i, qpl->zlen[i]);
690 + return -1;
691 + }
692 zbuf_len += qpl->zlen[i];
693 ramblock_recv_bitmap_set_offset(p->block, p->normal[i]);
694 }
695
696 /* read compressed pages */
686 - assert(in_size == len + zbuf_len);
697 + if (in_size != len + zbuf_len) {
698 + error_setg(errp, "multifd %u: packet size %"PRIu32
699 + " != header %"PRIu32" + data %"PRIu32,
700 + p->id, in_size, len, zbuf_len);
701 + return -1;
702 + }
703 ret = qio_channel_read_all(p->c, (void *) qpl->zbuf, zbuf_len, errp);
704 if (ret != 0) {
705 return ret;
migration/multifd-uadk.c
+20 -4
@@ -245,12 +245,19 @@ static int multifd_uadk_recv(MultiFDRecvParams *p, Error **errp)
245
246 multifd_recv_zero_page_process(p);
247 if (!p->normal_num) {
248 - assert(in_size == 0);
248 + if (in_size != 0) {
249 + error_setg(errp, "multifd %u: expected empty packet", p->id);
250 + return -1;
251 + }
252 return 0;
253 }
254
255 /* read compressed data lengths */
253 - assert(hdr_len < in_size);
256 + if (hdr_len >= in_size) {
257 + error_setg(errp, "multifd %u: header len %"PRIu32
258 + " >= packet size %"PRIu32, p->id, hdr_len, in_size);
259 + return -1;
260 + }
261 ret = qio_channel_read_all(p->c, (void *) uadk_data->buf_hdr,
262 hdr_len, errp);
263 if (ret != 0) {
@@ -259,12 +266,21 @@ static int multifd_uadk_recv(MultiFDRecvParams *p, Error **errp)
266
267 for (int i = 0; i < p->normal_num; i++) {
268 uadk_data->buf_hdr[i] = be32_to_cpu(uadk_data->buf_hdr[i]);
269 + if (uadk_data->buf_hdr[i] > page_size) {
270 + error_setg(errp, "multifd %u: page %d compressed len %"PRIu32
271 + " too large", p->id, i, uadk_data->buf_hdr[i]);
272 + return -1;
273 + }
274 data_len += uadk_data->buf_hdr[i];
263 - assert(uadk_data->buf_hdr[i] <= page_size);
275 }
276
277 /* read compressed data */
267 - assert(in_size == hdr_len + data_len);
278 + if (in_size != hdr_len + data_len) {
279 + error_setg(errp, "multifd %u: packet size %"PRIu32
280 + " != header %"PRIu32" + data %"PRIu32,
281 + p->id, in_size, hdr_len, data_len);
282 + return -1;
283 + }
284 ret = qio_channel_read_all(p->c, (void *)buf, data_len, errp);
285 if (ret != 0) {
286 return ret;