Skip to content

Commit

Permalink
RDMA/core: Sanitize WQ state received from the userspace
Browse files Browse the repository at this point in the history
[ Upstream commit f974428 ]

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: f213c05 ("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>
  • Loading branch information
rleon authored and gregkh committed Jul 14, 2021
1 parent 726d700 commit f354372
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 13 deletions.
21 changes: 19 additions & 2 deletions drivers/infiniband/core/uverbs_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -3033,12 +3033,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,
Expand Down
9 changes: 2 additions & 7 deletions drivers/infiniband/hw/mlx4/qp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4254,13 +4254,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;
Expand Down
6 changes: 2 additions & 4 deletions drivers/infiniband/hw/mlx5/qp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5309,10 +5309,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)
Expand Down

0 comments on commit f354372

Please sign in to comment.