IB/mlx5: Fix integer overflows in mlx5_ib_create_srq
authorBoris Pismenny <borisp@mellanox.com>
Thu, 8 Mar 2018 13:51:41 +0000 (15:51 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 24 Mar 2018 10:01:28 +0000 (11:01 +0100)
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
include/linux/mlx5/driver.h

index 6d5fadad909081d17b80c967cbe69b8c381e6bd8..3c7522d025f2b559f638fd2bde05200702488dde 100644 (file)
@@ -241,8 +241,8 @@ struct ib_srq *mlx5_ib_create_srq(struct ib_pd *pd,
 {
        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 ib_pd *pd,
 
        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)
index 8f9fc6e5539aaa61a361d97105e973339a38b284..bfb4a9d962a57fd525906596db2d5cd577b845aa 100644 (file)
@@ -432,8 +432,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);