* [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len @ 2013-08-07 2:26 Isaku Yamahata 2013-08-07 2:26 ` [Qemu-devel] [PATCH 1/3] rdma: use resp.len after validation in qemu_rdma_registration_stop Isaku Yamahata ` (6 more replies) 0 siblings, 7 replies; 8+ messages in thread From: Isaku Yamahata @ 2013-08-07 2:26 UTC (permalink / raw) To: qemu-devel; +Cc: owasserm, pbonzini, mrhines, quintela RDMAControlHeader::len is remote-provided. So validate the value before use. Isaku Yamahata (3): rdma: use resp.len after validation in qemu_rdma_registration_stop rdma: validate RDMAControlHeader::len rdma: check if RDMAControlHeader::len match transferred byte migration-rdma.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) -- 1.7.10.4 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 1/3] rdma: use resp.len after validation in qemu_rdma_registration_stop 2013-08-07 2:26 [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len Isaku Yamahata @ 2013-08-07 2:26 ` Isaku Yamahata 2013-08-07 2:26 ` [Qemu-devel] [PATCH 2/3] rdma: validate RDMAControlHeader::len Isaku Yamahata ` (5 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Isaku Yamahata @ 2013-08-07 2:26 UTC (permalink / raw) To: qemu-devel; +Cc: owasserm, pbonzini, mrhines, quintela resp.len is given from remote host. So should be validated before use. Otherwise memcpy can access beyond the buffer. Cc: Michael R. Hines <mrhines@us.ibm.com> Signed-off-by: Isaku Yamahata <yamahata@private.email.ne.jp> --- migration-rdma.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/migration-rdma.c b/migration-rdma.c index 3a380d4..6721266 100644 --- a/migration-rdma.c +++ b/migration-rdma.c @@ -3045,10 +3045,6 @@ static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque, return ret; } - qemu_rdma_move_header(rdma, reg_result_idx, &resp); - memcpy(rdma->block, - rdma->wr_data[reg_result_idx].control_curr, resp.len); - nb_remote_blocks = resp.len / sizeof(RDMARemoteBlock); /* @@ -3070,6 +3066,9 @@ static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque, return -EINVAL; } + qemu_rdma_move_header(rdma, reg_result_idx, &resp); + memcpy(rdma->block, + rdma->wr_data[reg_result_idx].control_curr, resp.len); for (i = 0; i < nb_remote_blocks; i++) { network_to_remote_block(&rdma->block[i]); -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 2/3] rdma: validate RDMAControlHeader::len 2013-08-07 2:26 [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len Isaku Yamahata 2013-08-07 2:26 ` [Qemu-devel] [PATCH 1/3] rdma: use resp.len after validation in qemu_rdma_registration_stop Isaku Yamahata @ 2013-08-07 2:26 ` Isaku Yamahata 2013-08-07 2:26 ` [Qemu-devel] [PATCH 3/3] rdma: check if RDMAControlHeader::len match transferred byte Isaku Yamahata ` (4 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Isaku Yamahata @ 2013-08-07 2:26 UTC (permalink / raw) To: qemu-devel; +Cc: owasserm, pbonzini, mrhines, quintela RMDAControlHeader::len is provided from remote, so validate it. Cc: Michael R. Hines <mrhines@us.ibm.com> Signed-off-by: Isaku Yamahata <yamahata@private.email.ne.jp> --- migration-rdma.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/migration-rdma.c b/migration-rdma.c index 6721266..ebe1f55 100644 --- a/migration-rdma.c +++ b/migration-rdma.c @@ -1424,6 +1424,7 @@ static int qemu_rdma_post_send_control(RDMAContext *rdma, uint8_t *buf, * The copy makes the RDMAControlHeader simpler to manipulate * for the time being. */ + assert(head->len <= RDMA_CONTROL_MAX_BUFFER - sizeof(*head)); memcpy(wr->control, head, sizeof(RDMAControlHeader)); control_to_network((void *) wr->control); @@ -1504,6 +1505,10 @@ static int qemu_rdma_exchange_get_response(RDMAContext *rdma, control_desc[head->type], head->type, head->len); return -EIO; } + if (head->len > RDMA_CONTROL_MAX_BUFFER - sizeof(*head)) { + fprintf(stderr, "too long length: %d\n", head->len); + return -EINVAL; + } return 0; } -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 3/3] rdma: check if RDMAControlHeader::len match transferred byte 2013-08-07 2:26 [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len Isaku Yamahata 2013-08-07 2:26 ` [Qemu-devel] [PATCH 1/3] rdma: use resp.len after validation in qemu_rdma_registration_stop Isaku Yamahata 2013-08-07 2:26 ` [Qemu-devel] [PATCH 2/3] rdma: validate RDMAControlHeader::len Isaku Yamahata @ 2013-08-07 2:26 ` Isaku Yamahata 2013-08-07 7:40 ` [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len Paolo Bonzini ` (3 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Isaku Yamahata @ 2013-08-07 2:26 UTC (permalink / raw) To: qemu-devel; +Cc: owasserm, pbonzini, mrhines, quintela RDMAControlHeader::len is provided from remote, so check if the value match the actual transferred byte_len. Cc: Michael R. Hines <mrhines@us.ibm.com> Signed-off-by: Isaku Yamahata <yamahata@private.email.ne.jp> --- migration-rdma.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/migration-rdma.c b/migration-rdma.c index ebe1f55..30e08cd 100644 --- a/migration-rdma.c +++ b/migration-rdma.c @@ -1214,7 +1214,8 @@ static void qemu_rdma_signal_unregister(RDMAContext *rdma, uint64_t index, * (of any kind) has completed. * Return the work request ID that completed. */ -static uint64_t qemu_rdma_poll(RDMAContext *rdma, uint64_t *wr_id_out) +static uint64_t qemu_rdma_poll(RDMAContext *rdma, uint64_t *wr_id_out, + uint32_t *byte_len) { int ret; struct ibv_wc wc; @@ -1285,6 +1286,9 @@ static uint64_t qemu_rdma_poll(RDMAContext *rdma, uint64_t *wr_id_out) } *wr_id_out = wc.wr_id; + if (byte_len) { + *byte_len = wc.byte_len; + } return 0; } @@ -1302,7 +1306,8 @@ static uint64_t qemu_rdma_poll(RDMAContext *rdma, uint64_t *wr_id_out) * completions only need to be recorded, but do not actually * need further processing. */ -static int qemu_rdma_block_for_wrid(RDMAContext *rdma, int wrid_requested) +static int qemu_rdma_block_for_wrid(RDMAContext *rdma, int wrid_requested, + uint32_t *byte_len) { int num_cq_events = 0, ret = 0; struct ibv_cq *cq; @@ -1314,7 +1319,7 @@ static int qemu_rdma_block_for_wrid(RDMAContext *rdma, int wrid_requested) } /* poll cq first */ while (wr_id != wrid_requested) { - ret = qemu_rdma_poll(rdma, &wr_id_in); + ret = qemu_rdma_poll(rdma, &wr_id_in, byte_len); if (ret < 0) { return ret; } @@ -1356,7 +1361,7 @@ static int qemu_rdma_block_for_wrid(RDMAContext *rdma, int wrid_requested) } while (wr_id != wrid_requested) { - ret = qemu_rdma_poll(rdma, &wr_id_in); + ret = qemu_rdma_poll(rdma, &wr_id_in, byte_len); if (ret < 0) { goto err_block_for_wrid; } @@ -1442,7 +1447,7 @@ static int qemu_rdma_post_send_control(RDMAContext *rdma, uint8_t *buf, return ret; } - ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_SEND_CONTROL); + ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_SEND_CONTROL, NULL); if (ret < 0) { fprintf(stderr, "rdma migration: send polling control error!\n"); } @@ -1483,7 +1488,9 @@ static int qemu_rdma_post_recv_control(RDMAContext *rdma, int idx) static int qemu_rdma_exchange_get_response(RDMAContext *rdma, RDMAControlHeader *head, int expecting, int idx) { - int ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RECV_CONTROL + idx); + uint32_t byte_len; + int ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RECV_CONTROL + idx, + &byte_len); if (ret < 0) { fprintf(stderr, "rdma migration: recv polling control error!\n"); @@ -1509,6 +1516,11 @@ static int qemu_rdma_exchange_get_response(RDMAContext *rdma, fprintf(stderr, "too long length: %d\n", head->len); return -EINVAL; } + if (sizeof(*head) + head->len != byte_len) { + fprintf(stderr, "Malformed length: %d byte_len %d\n", + head->len, byte_len); + return -EINVAL; + } return 0; } @@ -1738,7 +1750,7 @@ retry: count++, current_index, chunk, sge.addr, length, rdma->nb_sent, block->nb_chunks); - ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE); + ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE, NULL); if (ret < 0) { fprintf(stderr, "Failed to Wait for previous write to complete " @@ -1882,7 +1894,7 @@ retry: if (ret == ENOMEM) { DDPRINTF("send queue is full. wait a little....\n"); - ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE); + ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE, NULL); if (ret < 0) { fprintf(stderr, "rdma migration: failed to make " "room in full send queue! %d\n", ret); @@ -2471,7 +2483,7 @@ static int qemu_rdma_drain_cq(QEMUFile *f, RDMAContext *rdma) } while (rdma->nb_sent) { - ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE); + ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE, NULL); if (ret < 0) { fprintf(stderr, "rdma migration: complete polling error!\n"); return -EIO; @@ -2607,7 +2619,7 @@ static size_t qemu_rdma_save_page(QEMUFile *f, void *opaque, */ while (1) { uint64_t wr_id, wr_id_in; - int ret = qemu_rdma_poll(rdma, &wr_id_in); + int ret = qemu_rdma_poll(rdma, &wr_id_in, NULL); if (ret < 0) { fprintf(stderr, "rdma migration: polling error! %d\n", ret); goto err; -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len 2013-08-07 2:26 [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len Isaku Yamahata ` (2 preceding siblings ...) 2013-08-07 2:26 ` [Qemu-devel] [PATCH 3/3] rdma: check if RDMAControlHeader::len match transferred byte Isaku Yamahata @ 2013-08-07 7:40 ` Paolo Bonzini 2013-08-07 8:54 ` Orit Wasserman ` (2 subsequent siblings) 6 siblings, 0 replies; 8+ messages in thread From: Paolo Bonzini @ 2013-08-07 7:40 UTC (permalink / raw) To: Isaku Yamahata; +Cc: owasserm, mrhines, qemu-devel, quintela > RDMAControlHeader::len is remote-provided. So validate the value before use. > > Isaku Yamahata (3): > rdma: use resp.len after validation in qemu_rdma_registration_stop > rdma: validate RDMAControlHeader::len > rdma: check if RDMAControlHeader::len match transferred byte > > migration-rdma.c | 44 ++++++++++++++++++++++++++++++-------------- > 1 file changed, 30 insertions(+), 14 deletions(-) Looks good, thanks! We will have a mix of assertions and errors after this patch. Asserting on the destination is probably okay, but as a follow-up perhaps we can change the assertion(s) to errors. Paolo ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len 2013-08-07 2:26 [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len Isaku Yamahata ` (3 preceding siblings ...) 2013-08-07 7:40 ` [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len Paolo Bonzini @ 2013-08-07 8:54 ` Orit Wasserman 2013-08-07 15:02 ` Michael R. Hines 2013-08-14 16:27 ` Anthony Liguori 6 siblings, 0 replies; 8+ messages in thread From: Orit Wasserman @ 2013-08-07 8:54 UTC (permalink / raw) To: Isaku Yamahata; +Cc: pbonzini, mrhines, qemu-devel, quintela On 08/07/2013 05:26 AM, Isaku Yamahata wrote: > RDMAControlHeader::len is remote-provided. So validate the value before use. > > Isaku Yamahata (3): > rdma: use resp.len after validation in qemu_rdma_registration_stop > rdma: validate RDMAControlHeader::len > rdma: check if RDMAControlHeader::len match transferred byte > > migration-rdma.c | 44 ++++++++++++++++++++++++++++++-------------- > 1 file changed, 30 insertions(+), 14 deletions(-) > Series Reviewed-by: Orit Wasserman <owasserm@redhat.com> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len 2013-08-07 2:26 [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len Isaku Yamahata ` (4 preceding siblings ...) 2013-08-07 8:54 ` Orit Wasserman @ 2013-08-07 15:02 ` Michael R. Hines 2013-08-14 16:27 ` Anthony Liguori 6 siblings, 0 replies; 8+ messages in thread From: Michael R. Hines @ 2013-08-07 15:02 UTC (permalink / raw) To: Isaku Yamahata; +Cc: owasserm, quintela, mrhines, qemu-devel, pbonzini On 08/06/2013 10:26 PM, Isaku Yamahata wrote: > RDMAControlHeader::len is remote-provided. So validate the value before use. > > Isaku Yamahata (3): > rdma: use resp.len after validation in qemu_rdma_registration_stop > rdma: validate RDMAControlHeader::len > rdma: check if RDMAControlHeader::len match transferred byte > > migration-rdma.c | 44 ++++++++++++++++++++++++++++++-------------- > 1 file changed, 30 insertions(+), 14 deletions(-) > Thank you. I will apply to my tree and re-send. - Michael ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len 2013-08-07 2:26 [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len Isaku Yamahata ` (5 preceding siblings ...) 2013-08-07 15:02 ` Michael R. Hines @ 2013-08-14 16:27 ` Anthony Liguori 6 siblings, 0 replies; 8+ messages in thread From: Anthony Liguori @ 2013-08-14 16:27 UTC (permalink / raw) To: Isaku Yamahata, qemu-devel; +Cc: owasserm, quintela, mrhines, pbonzini Applied. Thanks. Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-08-14 16:28 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-08-07 2:26 [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len Isaku Yamahata 2013-08-07 2:26 ` [Qemu-devel] [PATCH 1/3] rdma: use resp.len after validation in qemu_rdma_registration_stop Isaku Yamahata 2013-08-07 2:26 ` [Qemu-devel] [PATCH 2/3] rdma: validate RDMAControlHeader::len Isaku Yamahata 2013-08-07 2:26 ` [Qemu-devel] [PATCH 3/3] rdma: check if RDMAControlHeader::len match transferred byte Isaku Yamahata 2013-08-07 7:40 ` [Qemu-devel] [PATCH 0/3] rdma: validate remote provided RDMAControlHeader::len Paolo Bonzini 2013-08-07 8:54 ` Orit Wasserman 2013-08-07 15:02 ` Michael R. Hines 2013-08-14 16:27 ` Anthony Liguori
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).