提交 c1e91244 编写于 作者: J Jason Gunthorpe 提交者: Yang Yingliang

RDMA/hns: Prevent undefined behavior in hns_roce_set_user_sq_size()

mainline  inclusion
from mainline-v5.5
commit 515f6000
category: bugfix
bugzilla: NA
CVE: NA

The "ucmd->log_sq_bb_count" variable is a user controlled variable in the
0-255 range.  If we shift more than then number of bits in an int then
it's undefined behavior (it shift wraps), and potentially the int could
become negative.

Fixes: 9a443537 ("IB/hns: Add driver files for hns RoCE driver")
Link: https://lore.kernel.org/r/20190608092514.GC28890@mwandaReported-by: NDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: NJason Gunthorpe <jgg@mellanox.com>
Reviewed-by: NDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: NShunfeng Yang <yangshunfeng2@huawei.com>
Reviewed-by: Nchunzhi hu <huchunzhi@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 53a6778b
...@@ -435,9 +435,8 @@ static int check_sq_size_with_integrity(struct hns_roce_dev *hr_dev, ...@@ -435,9 +435,8 @@ static int check_sq_size_with_integrity(struct hns_roce_dev *hr_dev,
u8 max_sq_stride = ilog2(roundup_sq_stride); u8 max_sq_stride = ilog2(roundup_sq_stride);
/* Sanity check SQ size before proceeding */ /* Sanity check SQ size before proceeding */
if ((u32)(1 << ucmd->log_sq_bb_count) > hr_dev->caps.max_wqes || if (ucmd->log_sq_stride > max_sq_stride ||
ucmd->log_sq_stride > max_sq_stride || ucmd->log_sq_stride < HNS_ROCE_IB_MIN_SQ_STRIDE) {
ucmd->log_sq_stride < HNS_ROCE_IB_MIN_SQ_STRIDE) {
dev_err(hr_dev->dev, dev_err(hr_dev->dev,
"Check SQ size error! Log sq stride 0x%x\n", "Check SQ size error! Log sq stride 0x%x\n",
ucmd->log_sq_stride); ucmd->log_sq_stride);
...@@ -464,6 +463,10 @@ static int hns_roce_set_user_sq_size(struct hns_roce_dev *hr_dev, ...@@ -464,6 +463,10 @@ static int hns_roce_set_user_sq_size(struct hns_roce_dev *hr_dev,
u32 max_cnt; u32 max_cnt;
int ret; int ret;
if (check_shl_overflow(1, ucmd->log_sq_bb_count, &hr_qp->sq.wqe_cnt) ||
hr_qp->sq.wqe_cnt > hr_dev->caps.max_wqes)
return -EINVAL;
ret = check_sq_size_with_integrity(hr_dev, cap, ucmd); ret = check_sq_size_with_integrity(hr_dev, cap, ucmd);
if (ret) { if (ret) {
dev_err(hr_dev->dev, "Sanity check sq(0x%lx) size fail\n", dev_err(hr_dev->dev, "Sanity check sq(0x%lx) size fail\n",
...@@ -471,7 +474,6 @@ static int hns_roce_set_user_sq_size(struct hns_roce_dev *hr_dev, ...@@ -471,7 +474,6 @@ static int hns_roce_set_user_sq_size(struct hns_roce_dev *hr_dev,
return ret; return ret;
} }
hr_qp->sq.wqe_cnt = 1 << ucmd->log_sq_bb_count;
hr_qp->sq.wqe_shift = ucmd->log_sq_stride; hr_qp->sq.wqe_shift = ucmd->log_sq_stride;
if ((u32)hr_qp->sq.wqe_cnt > hr_dev->caps.max_wqes) { if ((u32)hr_qp->sq.wqe_cnt > hr_dev->caps.max_wqes) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册