@samitouri / QOSamiQemu / commits / 24dbf7e24d

migration/rdma: Sanity check RDMA_CONTROL_REGISTER_REQUEST on buflen

RDMA header supports head.repeat on RDMA_CONTROL_REGISTER_REQUEST, which can include >1 memory registrations. The current code did check over head.repeat to guard against RDMA_CONTROL_MAX_COMMANDS_PER_MESSAGE, however it didn't further check the buffer size (head.len) to make sure the received data is large enough to include the repeated entries. Check it. This is almost only to harden this piece of code, in reality on source side QEMU never uses repeat>1.. However since it's a protocol, still keep it. Check the buffer size instead. In case it's not obvious to new RDMA readers: head.len should be the size RDMA has last received, as qemu_rdma_exchange_get_response() checked on it against byte_len (which was further fetched from ibv_wc.byte_len in qemu_rdma_poll()). Reported-by: Tristan (@TristanInSec) Closes: https://gitlab.com/qemu-project/qemu/-/work_items/4028 Reviewed-by: Jinpu Wang <jinpu.wang@cloud.ionos.com> Signed-off-by: Peter Xu <peterx@redhat.com> Reviewed-by: Fabiano Rosas <farosas@suse.de> Reviewed-by: Jack Wang <jinpu.wang@cloud.ionos.com> Signed-off-by: Fabiano Rosas <farosas@suse.de>

Peter Xu committed Aug 20, 2026 at 16:03 UTC 24dbf7e24d83d50237c7ec5166a02a703b1359f3
1 file changed +8
migration/rdma.c
+8
@@ -3360,6 +3360,14 @@ int rdma_registration_handle(QEMUFile *f)
3360 reg_resp.repeat = head.repeat;
3361 registers = (RDMARegister *) rdma->wr_data[idx].control_curr;
3362
3363 + /* Making sure the register buffers to read are valid */
3364 + if (head.len != head.repeat * sizeof(RDMARegister)) {
3365 + error_report("%s: Invalid RDMA_CONTROL_REGISTER_REQUEST "
3366 + "(head.repeat=%"PRIu32", head.len=%"PRIu32")",
3367 + __func__, head.repeat, head.len);
3368 + goto err;
3369 + }
3370 +
3371 for (int count = 0; count < head.repeat; count++) {
3372 uint64_t chunk;
3373 uint8_t *chunk_start, *chunk_end;