Commit 1c0ca9cd authored by Wenpeng Liang's avatar Wenpeng Liang Committed by Jason Gunthorpe

RDMA/hns: Limit the length of data copied between kernel and userspace

For ib_copy_from_user(), the length of udata may not be the same as that
of cmd. For ib_copy_to_user(), the length of udata may not be the same as
that of resp. So limit the length to prevent out-of-bounds read and write
operations from ib_copy_from_user() and ib_copy_to_user().

Fixes: de77503a ("RDMA/hns: RDMA/hns: Assign rq head pointer when enable rq record db")
Fixes: 633fb4d9 ("RDMA/hns: Use structs to describe the uABI instead of opencoding")
Fixes: ae85bf92 ("RDMA/hns: Optimize qp param setup flow")
Fixes: 6fd610c5 ("RDMA/hns: Support 0 hop addressing for SRQ buffer")
Fixes: 9d9d4ff7 ("RDMA/hns: Update the kernel header file of hns")
Link: https://lore.kernel.org/r/1607650657-35992-2-git-send-email-liweihang@huawei.comSigned-off-by: default avatarWenpeng Liang <liangwenpeng@huawei.com>
Signed-off-by: default avatarWeihang Li <liweihang@huawei.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 6f320f69
...@@ -276,7 +276,7 @@ int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr, ...@@ -276,7 +276,7 @@ int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr,
if (udata) { if (udata) {
ret = ib_copy_from_udata(&ucmd, udata, ret = ib_copy_from_udata(&ucmd, udata,
min(sizeof(ucmd), udata->inlen)); min(udata->inlen, sizeof(ucmd)));
if (ret) { if (ret) {
ibdev_err(ibdev, "Failed to copy CQ udata, err %d\n", ibdev_err(ibdev, "Failed to copy CQ udata, err %d\n",
ret); ret);
...@@ -315,7 +315,8 @@ int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr, ...@@ -315,7 +315,8 @@ int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr,
if (udata) { if (udata) {
resp.cqn = hr_cq->cqn; resp.cqn = hr_cq->cqn;
ret = ib_copy_to_udata(udata, &resp, sizeof(resp)); ret = ib_copy_to_udata(udata, &resp,
min(udata->outlen, sizeof(resp)));
if (ret) if (ret)
goto err_cqc; goto err_cqc;
} }
......
...@@ -327,7 +327,8 @@ static int hns_roce_alloc_ucontext(struct ib_ucontext *uctx, ...@@ -327,7 +327,8 @@ static int hns_roce_alloc_ucontext(struct ib_ucontext *uctx,
resp.cqe_size = hr_dev->caps.cqe_sz; resp.cqe_size = hr_dev->caps.cqe_sz;
ret = ib_copy_to_udata(udata, &resp, sizeof(resp)); ret = ib_copy_to_udata(udata, &resp,
min(udata->outlen, sizeof(resp)));
if (ret) if (ret)
goto error_fail_copy_to_udata; goto error_fail_copy_to_udata;
......
...@@ -69,16 +69,17 @@ int hns_roce_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) ...@@ -69,16 +69,17 @@ int hns_roce_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
} }
if (udata) { if (udata) {
struct hns_roce_ib_alloc_pd_resp uresp = {.pdn = pd->pdn}; struct hns_roce_ib_alloc_pd_resp resp = {.pdn = pd->pdn};
if (ib_copy_to_udata(udata, &uresp, sizeof(uresp))) { ret = ib_copy_to_udata(udata, &resp,
min(udata->outlen, sizeof(resp)));
if (ret) {
hns_roce_pd_free(to_hr_dev(ib_dev), pd->pdn); hns_roce_pd_free(to_hr_dev(ib_dev), pd->pdn);
ibdev_err(ib_dev, "failed to copy to udata\n"); ibdev_err(ib_dev, "failed to copy to udata, ret = %d\n", ret);
return -EFAULT;
} }
} }
return 0; return ret;
} }
int hns_roce_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata) int hns_roce_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
......
...@@ -924,9 +924,12 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, ...@@ -924,9 +924,12 @@ static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
} }
if (udata) { if (udata) {
if (ib_copy_from_udata(ucmd, udata, sizeof(*ucmd))) { ret = ib_copy_from_udata(ucmd, udata,
ibdev_err(ibdev, "Failed to copy QP ucmd\n"); min(udata->inlen, sizeof(*ucmd)));
return -EFAULT; if (ret) {
ibdev_err(ibdev,
"failed to copy QP ucmd, ret = %d\n", ret);
return ret;
} }
ret = set_user_sq_size(hr_dev, &init_attr->cap, hr_qp, ucmd); ret = set_user_sq_size(hr_dev, &init_attr->cap, hr_qp, ucmd);
......
...@@ -303,7 +303,8 @@ int hns_roce_create_srq(struct ib_srq *ib_srq, ...@@ -303,7 +303,8 @@ int hns_roce_create_srq(struct ib_srq *ib_srq,
srq->max_gs = init_attr->attr.max_sge; srq->max_gs = init_attr->attr.max_sge;
if (udata) { if (udata) {
ret = ib_copy_from_udata(&ucmd, udata, sizeof(ucmd)); ret = ib_copy_from_udata(&ucmd, udata,
min(udata->inlen, sizeof(ucmd)));
if (ret) { if (ret) {
ibdev_err(ibdev, "Failed to copy SRQ udata, err %d\n", ibdev_err(ibdev, "Failed to copy SRQ udata, err %d\n",
ret); ret);
...@@ -346,12 +347,11 @@ int hns_roce_create_srq(struct ib_srq *ib_srq, ...@@ -346,12 +347,11 @@ int hns_roce_create_srq(struct ib_srq *ib_srq,
resp.srqn = srq->srqn; resp.srqn = srq->srqn;
if (udata) { if (udata) {
if (ib_copy_to_udata(udata, &resp, ret = ib_copy_to_udata(udata, &resp,
min(udata->outlen, sizeof(resp)))) { min(udata->outlen, sizeof(resp)));
ret = -EFAULT; if (ret)
goto err_srqc_alloc; goto err_srqc_alloc;
} }
}
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment