On Mon, Aug 17, 2026 at 10:24 PM Peter Xu <[email protected]> wrote:
>
> 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
> Signed-off-by: Peter Xu <[email protected]>
Reviewed-by: Jack Wang <[email protected]>
> ---
> migration/rdma.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/migration/rdma.c b/migration/rdma.c
> index f64bcee418..5ce8b06818 100644
> --- a/migration/rdma.c
> +++ b/migration/rdma.c
> @@ -3362,6 +3362,14 @@ int rdma_registration_handle(QEMUFile *f)
> reg_resp.repeat = head.repeat;
> registers = (RDMARegister *) rdma->wr_data[idx].control_curr;
>
> + /* Making sure the register buffers to read are valid */
> + if (head.len != head.repeat * sizeof(RDMARegister)) {
> + error_report("%s: Invalid RDMA_CONTROL_REGISTER_REQUEST "
> + "(head.repeat=%"PRIu32", head.len=%"PRIu32")",
> + __func__, head.repeat, head.len);
> + goto err;
> + }
> +
> for (int count = 0; count < head.repeat; count++) {
> uint64_t chunk;
> uint8_t *chunk_start, *chunk_end;
> --
> 2.54.0
>