| From c2b37f76485f073f020e60b5954b6dc4e55f693c Mon Sep 17 00:00:00 2001 |
| From: Boris Pismenny <borisp@mellanox.com> |
| Date: Thu, 8 Mar 2018 15:51:41 +0200 |
| Subject: IB/mlx5: Fix integer overflows in mlx5_ib_create_srq |
| |
| From: Boris Pismenny <borisp@mellanox.com> |
| |
| commit c2b37f76485f073f020e60b5954b6dc4e55f693c upstream. |
| |
| This patch validates user provided input to prevent integer overflow due |
| to integer manipulation in the mlx5_ib_create_srq function. |
| |
| Cc: syzkaller <syzkaller@googlegroups.com> |
| Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters") |
| Signed-off-by: Boris Pismenny <borisp@mellanox.com> |
| Signed-off-by: Leon Romanovsky <leon@kernel.org> |
| Signed-off-by: Doug Ledford <dledford@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/infiniband/hw/mlx5/srq.c | 15 +++++++++------ |
| include/linux/mlx5/driver.h | 4 ++-- |
| 2 files changed, 11 insertions(+), 8 deletions(-) |
| |
| --- a/drivers/infiniband/hw/mlx5/srq.c |
| +++ b/drivers/infiniband/hw/mlx5/srq.c |
| @@ -241,8 +241,8 @@ struct ib_srq *mlx5_ib_create_srq(struct |
| { |
| struct mlx5_ib_dev *dev = to_mdev(pd->device); |
| struct mlx5_ib_srq *srq; |
| - int desc_size; |
| - int buf_size; |
| + size_t desc_size; |
| + size_t buf_size; |
| int err; |
| struct mlx5_srq_attr in = {0}; |
| __u32 max_srq_wqes = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz); |
| @@ -266,15 +266,18 @@ struct ib_srq *mlx5_ib_create_srq(struct |
| |
| desc_size = sizeof(struct mlx5_wqe_srq_next_seg) + |
| srq->msrq.max_gs * sizeof(struct mlx5_wqe_data_seg); |
| + if (desc_size == 0 || srq->msrq.max_gs > desc_size) |
| + return ERR_PTR(-EINVAL); |
| desc_size = roundup_pow_of_two(desc_size); |
| - desc_size = max_t(int, 32, desc_size); |
| + desc_size = max_t(size_t, 32, desc_size); |
| + if (desc_size < sizeof(struct mlx5_wqe_srq_next_seg)) |
| + return ERR_PTR(-EINVAL); |
| srq->msrq.max_avail_gather = (desc_size - sizeof(struct mlx5_wqe_srq_next_seg)) / |
| sizeof(struct mlx5_wqe_data_seg); |
| srq->msrq.wqe_shift = ilog2(desc_size); |
| buf_size = srq->msrq.max * desc_size; |
| - mlx5_ib_dbg(dev, "desc_size 0x%x, req wr 0x%x, srq size 0x%x, max_gs 0x%x, max_avail_gather 0x%x\n", |
| - desc_size, init_attr->attr.max_wr, srq->msrq.max, srq->msrq.max_gs, |
| - srq->msrq.max_avail_gather); |
| + if (buf_size < desc_size) |
| + return ERR_PTR(-EINVAL); |
| in.type = init_attr->srq_type; |
| |
| if (pd->uobject) |
| --- a/include/linux/mlx5/driver.h |
| +++ b/include/linux/mlx5/driver.h |
| @@ -442,8 +442,8 @@ struct mlx5_core_srq { |
| struct mlx5_core_rsc_common common; /* must be first */ |
| u32 srqn; |
| int max; |
| - int max_gs; |
| - int max_avail_gather; |
| + size_t max_gs; |
| + size_t max_avail_gather; |
| int wqe_shift; |
| void (*event) (struct mlx5_core_srq *, enum mlx5_event); |
| |