| From 8421de1b9dac29fe1d458b639a082ddde453e46e Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 19 May 2021 11:37:31 +0300 |
| Subject: RDMA/core: Sanitize WQ state received from the userspace |
| |
| From: Leon Romanovsky <leonro@nvidia.com> |
| |
| [ Upstream commit f97442887275d11c88c2899e720fe945c1f61488 ] |
| |
| The mlx4 and mlx5 implemented differently the WQ input checks. Instead of |
| duplicating mlx4 logic in the mlx5, let's prepare the input in the central |
| place. |
| |
| The mlx5 implementation didn't check for validity of state input. It is |
| not real bug because our FW checked that, but still worth to fix. |
| |
| Fixes: f213c0527210 ("IB/uverbs: Add WQ support") |
| Link: https://lore.kernel.org/r/ac41ad6a81b095b1a8ad453dcf62cf8d3c5da779.1621413310.git.leonro@nvidia.com |
| Reported-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com> |
| Signed-off-by: Leon Romanovsky <leonro@nvidia.com> |
| Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/infiniband/core/uverbs_cmd.c | 21 +++++++++++++++++++-- |
| drivers/infiniband/hw/mlx4/qp.c | 9 ++------- |
| drivers/infiniband/hw/mlx5/qp.c | 6 ++---- |
| 3 files changed, 23 insertions(+), 13 deletions(-) |
| |
| diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c |
| index 418d133a8fb0..466026825dd7 100644 |
| --- a/drivers/infiniband/core/uverbs_cmd.c |
| +++ b/drivers/infiniband/core/uverbs_cmd.c |
| @@ -3000,12 +3000,29 @@ static int ib_uverbs_ex_modify_wq(struct uverbs_attr_bundle *attrs) |
| if (!wq) |
| return -EINVAL; |
| |
| - wq_attr.curr_wq_state = cmd.curr_wq_state; |
| - wq_attr.wq_state = cmd.wq_state; |
| if (cmd.attr_mask & IB_WQ_FLAGS) { |
| wq_attr.flags = cmd.flags; |
| wq_attr.flags_mask = cmd.flags_mask; |
| } |
| + |
| + if (cmd.attr_mask & IB_WQ_CUR_STATE) { |
| + if (cmd.curr_wq_state > IB_WQS_ERR) |
| + return -EINVAL; |
| + |
| + wq_attr.curr_wq_state = cmd.curr_wq_state; |
| + } else { |
| + wq_attr.curr_wq_state = wq->state; |
| + } |
| + |
| + if (cmd.attr_mask & IB_WQ_STATE) { |
| + if (cmd.wq_state > IB_WQS_ERR) |
| + return -EINVAL; |
| + |
| + wq_attr.wq_state = cmd.wq_state; |
| + } else { |
| + wq_attr.wq_state = wq_attr.curr_wq_state; |
| + } |
| + |
| ret = wq->device->ops.modify_wq(wq, &wq_attr, cmd.attr_mask, |
| &attrs->driver_udata); |
| rdma_lookup_put_uobject(&wq->uobject->uevent.uobject, |
| diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c |
| index 5cb8e602294c..6bc0818f4b2c 100644 |
| --- a/drivers/infiniband/hw/mlx4/qp.c |
| +++ b/drivers/infiniband/hw/mlx4/qp.c |
| @@ -4244,13 +4244,8 @@ int mlx4_ib_modify_wq(struct ib_wq *ibwq, struct ib_wq_attr *wq_attr, |
| if (wq_attr_mask & IB_WQ_FLAGS) |
| return -EOPNOTSUPP; |
| |
| - cur_state = wq_attr_mask & IB_WQ_CUR_STATE ? wq_attr->curr_wq_state : |
| - ibwq->state; |
| - new_state = wq_attr_mask & IB_WQ_STATE ? wq_attr->wq_state : cur_state; |
| - |
| - if (cur_state < IB_WQS_RESET || cur_state > IB_WQS_ERR || |
| - new_state < IB_WQS_RESET || new_state > IB_WQS_ERR) |
| - return -EINVAL; |
| + cur_state = wq_attr->curr_wq_state; |
| + new_state = wq_attr->wq_state; |
| |
| if ((new_state == IB_WQS_RDY) && (cur_state == IB_WQS_ERR)) |
| return -EINVAL; |
| diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c |
| index 6d2715f65d78..8beba002e5dd 100644 |
| --- a/drivers/infiniband/hw/mlx5/qp.c |
| +++ b/drivers/infiniband/hw/mlx5/qp.c |
| @@ -5236,10 +5236,8 @@ int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr, |
| |
| rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx); |
| |
| - curr_wq_state = (wq_attr_mask & IB_WQ_CUR_STATE) ? |
| - wq_attr->curr_wq_state : wq->state; |
| - wq_state = (wq_attr_mask & IB_WQ_STATE) ? |
| - wq_attr->wq_state : curr_wq_state; |
| + curr_wq_state = wq_attr->curr_wq_state; |
| + wq_state = wq_attr->wq_state; |
| if (curr_wq_state == IB_WQS_ERR) |
| curr_wq_state = MLX5_RQC_STATE_ERR; |
| if (wq_state == IB_WQS_ERR) |
| -- |
| 2.30.2 |
| |