Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 147280d8 authored by James Simmons's avatar James Simmons Committed by Greg Kroah-Hartman
Browse files

staging: lustre: ko2iblnd: fix memory corruption with fragments



In my test of the upstream client this change exposed a long
standing issues where we have a offset that is not page algined
would causes us to access memory beyond the scatter gather list
which was causing memory corruption when all 256 fragments were
in use.

Signed-off-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent cd779f2e
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -2011,7 +2011,7 @@ static void kiblnd_destroy_tx_pool(kib_pool_t *pool)
				    sizeof(*tx->tx_pages));
		if (tx->tx_frags)
			LIBCFS_FREE(tx->tx_frags,
				    IBLND_MAX_RDMA_FRAGS *
				    (1 + IBLND_MAX_RDMA_FRAGS) *
				     sizeof(*tx->tx_frags));
		if (tx->tx_wrq)
			LIBCFS_FREE(tx->tx_wrq,
@@ -2090,11 +2090,12 @@ static int kiblnd_create_tx_pool(kib_poolset_t *ps, int size,
		}

		LIBCFS_CPT_ALLOC(tx->tx_frags, lnet_cpt_table(), ps->ps_cpt,
				 IBLND_MAX_RDMA_FRAGS * sizeof(*tx->tx_frags));
				 (1 + IBLND_MAX_RDMA_FRAGS) *
				 sizeof(*tx->tx_frags));
		if (!tx->tx_frags)
			break;

		sg_init_table(tx->tx_frags, IBLND_MAX_RDMA_FRAGS);
		sg_init_table(tx->tx_frags, IBLND_MAX_RDMA_FRAGS + 1);

		LIBCFS_CPT_ALLOC(tx->tx_wrq, lnet_cpt_table(), ps->ps_cpt,
				 (1 + IBLND_MAX_RDMA_FRAGS) *
+8 −0
Original line number Diff line number Diff line
@@ -689,6 +689,10 @@ kiblnd_setup_rd_iov(lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd,

		sg_set_page(sg, page, fragnob, page_offset);
		sg = sg_next(sg);
		if (!sg) {
			CERROR("lacking enough sg entries to map tx\n");
			return -EFAULT;
		}

		if (offset + fragnob < iov->iov_len) {
			offset += fragnob;
@@ -733,6 +737,10 @@ kiblnd_setup_rd_kiov(lnet_ni_t *ni, kib_tx_t *tx, kib_rdma_desc_t *rd,
		sg_set_page(sg, kiov->kiov_page, fragnob,
			    kiov->kiov_offset + offset);
		sg = sg_next(sg);
		if (!sg) {
			CERROR("lacking enough sg entries to map tx\n");
			return -EFAULT;
		}

		offset = 0;
		kiov++;