RDMA/core: Sanitize WQ state received from the userspace
authorLeon Romanovsky <leonro@nvidia.com>
Wed, 19 May 2021 08:37:31 +0000 (11:37 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 14 Jul 2021 14:56:19 +0000 (16:56 +0200)
[ 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
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/mlx5/qp.c

index 418d133a8fb080f6ef175c59f2a1f6ccbfc6864f..466026825dd7548192a9d4a0f44d1302a8986390 100644 (file)
@@ -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,
index 5cb8e602294ca9ad1e89000991c307d84b3984a1..6bc0818f4b2c6f6b8ebecdc85b3bddd8348f934b 100644 (file)
@@ -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;
index 6d2715f65d788e870811d00327629e891e502dd3..8beba002e5dd7da2ec7fb3ccf2d92aaea5352547 100644 (file)
@@ -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)