From 2653621c332c79ba591d76a442061bd13ad23030 Mon Sep 17 00:00:00 2001
From: Luoyouming <luoyouming@huawei.com>
Date: Sat, 6 May 2023 18:06:39 +0800
Subject: [PATCH 2/3] libhns: Fix sge tail_len overflow

mainline inclusion
commit cd9c9ea5
category: bugfix
bugzilla: https://gitee.com/src-openeuler/rdma-core/issues/I72F0C
CVE: NA

----------------------------------------------------------------------

In the sq inline scenario, when num_sge in post_send is not 1, sge
array appears in the for loop without rotation and directly copy
out of bounds.

The fill_ext_sge_inl_data() calculates the remaining length of the
array by subtracting the current address from the tail address. If
the length is not sufficient, redundant data will be copied after
rotating the array. However, in the code, sge_cnt & sge_mask always
equals to 0, which causes the tail address of the array to be
mistakenly taken as the first address. Additionally, tail_len will
be either 0 or may overflow when calculating this value. After
overflowing to a very large number, the driver makes an incorrect
judgment and copies all the data directly. When the data length
exceeds the remaining length, an out-of-bounds problem with the
array will occur.

This patch modifies tail_bound_addr(tail pointer) to the actual sge
array tail address.

Fixes: 2ced2bc4d1d4 ("libhns: Fix out-of-bounds write when filling inline data into extended sge space")
Signed-off-by: Luoyouming <luoyouming@huawei.com>
Signed-off-by: Zhou Juan <nnuzj07170227@163.com>
---
 providers/hns/hns_roce_u_hw_v2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/providers/hns/hns_roce_u_hw_v2.c b/providers/hns/hns_roce_u_hw_v2.c
index 5533cdb..3d46f35 100644
--- a/providers/hns/hns_roce_u_hw_v2.c
+++ b/providers/hns/hns_roce_u_hw_v2.c
@@ -1028,7 +1028,7 @@ static int fill_ext_sge_inl_data(struct hns_roce_qp *qp,
 		return EINVAL;
 
 	dst_addr = get_send_sge_ex(qp, sge_info->start_idx & sge_mask);
-	tail_bound_addr = get_send_sge_ex(qp, qp->ex_sge.sge_cnt & sge_mask);
+	tail_bound_addr = get_send_sge_ex(qp, qp->ex_sge.sge_cnt);
 
 	for (i = 0; i < num_buf; i++) {
 		tail_len = (uintptr_t)tail_bound_addr - (uintptr_t)dst_addr;
-- 
2.25.1

