* [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).