From: Benoît Ganne Date: Mon, 5 Aug 2019 15:07:20 +0000 (+0200) Subject: rdma: fix double-free in rdma-tx X-Git-Tag: v20.01-rc0~10 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=dd1ccb4fd3b4428714ffcc5bd669fb8c11e46e8e rdma: fix double-free in rdma-tx In case of tx success after multiple retries, the last buffers to be enqueued will be both enqueued for tx and freed. Type: fix Fixes: 211ef2eb24 Change-Id: I57d218cff58b74c1f3d6dc5722624327f0821758 Signed-off-by: Benoît Ganne --- diff --git a/src/plugins/rdma/input.c b/src/plugins/rdma/input.c index 7ced1ec66d4..f5091db4719 100644 --- a/src/plugins/rdma/input.c +++ b/src/plugins/rdma/input.c @@ -128,12 +128,12 @@ rdma_device_input_refill (vlib_main_t * vm, rdma_device_t * rd, w[-1].next = 0; /* fix next pointer in WR linked-list last item */ - w = wr; - ibv_post_wq_recv (rxq->wq, wr, &w); - n = wr == w ? n_alloc : (uintptr_t) (w - wr); - - if (PREDICT_FALSE (n != n_alloc)) - vlib_buffer_free (vm, buffers + n, n_alloc - n); + n = n_alloc; + if (ibv_post_wq_recv (rxq->wq, wr, &w) != 0) + { + n = w - wr; + vlib_buffer_free (vm, buffers + n, n_alloc - n); + } rxq->n_enq += n; } diff --git a/src/plugins/rdma/output.c b/src/plugins/rdma/output.c index bb25abe1a98..ddda81a4b19 100644 --- a/src/plugins/rdma/output.c +++ b/src/plugins/rdma/output.c @@ -57,7 +57,7 @@ VNET_DEVICE_CLASS_TX_FN (rdma_device_class) (vlib_main_t * vm, vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs; struct ibv_send_wr wr[VLIB_FRAME_SIZE], *w = wr; struct ibv_sge sge[VLIB_FRAME_SIZE], *s = sge; - int i; + int i, ret; f = from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; @@ -155,12 +155,13 @@ VNET_DEVICE_CLASS_TX_FN (rdma_device_class) (vlib_main_t * vm, for (i = 0; i < 5; i++) { rdma_device_output_free (vm, txq); - if (0 == ibv_post_send (txq->qp, w, &w)) + ret = ibv_post_send (txq->qp, w, &w); + if (0 == ret) break; } clib_spinlock_unlock_if_init (&txq->lock); - n_tx_packets = w == wr ? frame->n_vectors : w - wr; + n_tx_packets = 0 == ret ? frame->n_vectors : w - wr; n_tx_failed = frame->n_vectors - n_tx_packets; if (PREDICT_FALSE (n_tx_failed))