Go treewide and consolidate all existing patterns using: * offsetofend() and variations * ib_is_udata_cleared() * ib_copy_from_udata()
into a direct call to the new ib_copy_validate_udata_in(). Signed-off-by: Jason Gunthorpe <[email protected]> --- drivers/infiniband/hw/efa/efa_verbs.c | 47 +++--------------------- drivers/infiniband/hw/irdma/verbs.c | 10 +++--- drivers/infiniband/hw/mlx4/qp.c | 38 ++++---------------- drivers/infiniband/hw/mlx5/qp.c | 51 ++++++--------------------- 4 files changed, 26 insertions(+), 120 deletions(-) diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c index fc498663cd372f..8d9357e2d513bb 100644 --- a/drivers/infiniband/hw/efa/efa_verbs.c +++ b/drivers/infiniband/hw/efa/efa_verbs.c @@ -699,29 +699,9 @@ int efa_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr, if (err) goto err_out; - if (offsetofend(typeof(cmd), driver_qp_type) > udata->inlen) { - ibdev_dbg(&dev->ibdev, - "Incompatible ABI params, no input udata\n"); - err = -EINVAL; + err = ib_copy_validate_udata_in(udata, cmd, driver_qp_type); + if (err) goto err_out; - } - - if (udata->inlen > sizeof(cmd) && - !ib_is_udata_cleared(udata, sizeof(cmd), - udata->inlen - sizeof(cmd))) { - ibdev_dbg(&dev->ibdev, - "Incompatible ABI params, unknown fields in udata\n"); - err = -EINVAL; - goto err_out; - } - - err = ib_copy_from_udata(&cmd, udata, - min(sizeof(cmd), udata->inlen)); - if (err) { - ibdev_dbg(&dev->ibdev, - "Cannot copy udata for create_qp\n"); - goto err_out; - } if (cmd.comp_mask || !is_reserved_cleared(cmd.reserved_98)) { ibdev_dbg(&dev->ibdev, @@ -1160,28 +1140,9 @@ int efa_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, goto err_out; } - if (offsetofend(typeof(cmd), num_sub_cqs) > udata->inlen) { - ibdev_dbg(ibdev, - "Incompatible ABI params, no input udata\n"); - err = -EINVAL; + err = ib_copy_validate_udata_in(udata, cmd, num_sub_cqs); + if (err) goto err_out; - } - - if (udata->inlen > sizeof(cmd) && - !ib_is_udata_cleared(udata, sizeof(cmd), - udata->inlen - sizeof(cmd))) { - ibdev_dbg(ibdev, - "Incompatible ABI params, unknown fields in udata\n"); - err = -EINVAL; - goto err_out; - } - - err = ib_copy_from_udata(&cmd, udata, - min(sizeof(cmd), udata->inlen)); - if (err) { - ibdev_dbg(ibdev, "Cannot copy udata for create_cq\n"); - goto err_out; - } if (cmd.comp_mask || !is_reserved_cleared(cmd.reserved_58)) { ibdev_dbg(ibdev, diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c index 7251cd7a21471e..b2978632241900 100644 --- a/drivers/infiniband/hw/irdma/verbs.c +++ b/drivers/infiniband/hw/irdma/verbs.c @@ -284,7 +284,6 @@ static void irdma_alloc_push_page(struct irdma_qp *iwqp) static int irdma_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata) { -#define IRDMA_ALLOC_UCTX_MIN_REQ_LEN offsetofend(struct irdma_alloc_ucontext_req, rsvd8) #define IRDMA_ALLOC_UCTX_MIN_RESP_LEN offsetofend(struct irdma_alloc_ucontext_resp, rsvd) struct ib_device *ibdev = uctx->device; struct irdma_device *iwdev = to_iwdev(ibdev); @@ -292,13 +291,14 @@ static int irdma_alloc_ucontext(struct ib_ucontext *uctx, struct irdma_alloc_ucontext_resp uresp = {}; struct irdma_ucontext *ucontext = to_ucontext(uctx); struct irdma_uk_attrs *uk_attrs = &iwdev->rf->sc_dev.hw_attrs.uk_attrs; + int ret; - if (udata->inlen < IRDMA_ALLOC_UCTX_MIN_REQ_LEN || - udata->outlen < IRDMA_ALLOC_UCTX_MIN_RESP_LEN) + if (udata->outlen < IRDMA_ALLOC_UCTX_MIN_RESP_LEN) return -EINVAL; - if (ib_copy_from_udata(&req, udata, min(sizeof(req), udata->inlen))) - return -EINVAL; + ret = ib_copy_validate_udata_in(udata, req, rsvd8); + if (ret) + return ret; if (req.userspace_ver < 4 || req.userspace_ver > IRDMA_ABI_VER) goto ver_error; diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 1cb890d3d93cea..b87a4b7949a3a0 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -710,7 +710,6 @@ static int _mlx4_ib_create_qp_rss(struct ib_pd *pd, struct mlx4_ib_qp *qp, struct ib_udata *udata) { struct mlx4_ib_create_qp_rss ucmd = {}; - size_t required_cmd_sz; int err; if (!udata) { @@ -721,16 +720,10 @@ static int _mlx4_ib_create_qp_rss(struct ib_pd *pd, struct mlx4_ib_qp *qp, if (udata->outlen) return -EOPNOTSUPP; - required_cmd_sz = offsetof(typeof(ucmd), reserved1) + - sizeof(ucmd.reserved1); - if (udata->inlen < required_cmd_sz) { - pr_debug("invalid inlen\n"); - return -EINVAL; - } - - if (ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen))) { + err = ib_copy_validate_udata_in(udata, ucmd, reserved1); + if (err) { pr_debug("copy failed\n"); - return -EFAULT; + return err; } if (memchr_inv(ucmd.reserved, 0, sizeof(ucmd.reserved))) @@ -739,13 +732,6 @@ static int _mlx4_ib_create_qp_rss(struct ib_pd *pd, struct mlx4_ib_qp *qp, if (ucmd.comp_mask || ucmd.reserved1) return -EOPNOTSUPP; - if (udata->inlen > sizeof(ucmd) && - !ib_is_udata_cleared(udata, sizeof(ucmd), - udata->inlen - sizeof(ucmd))) { - pr_debug("inlen is not supported\n"); - return -EOPNOTSUPP; - } - if (init_attr->qp_type != IB_QPT_RAW_PACKET) { pr_debug("RSS QP with unsupported QP type %d\n", init_attr->qp_type); @@ -4269,22 +4255,12 @@ int mlx4_ib_modify_wq(struct ib_wq *ibwq, struct ib_wq_attr *wq_attr, { struct mlx4_ib_qp *qp = to_mqp((struct ib_qp *)ibwq); struct mlx4_ib_modify_wq ucmd = {}; - size_t required_cmd_sz; enum ib_wq_state cur_state, new_state; - int err = 0; + int err; - required_cmd_sz = offsetof(typeof(ucmd), reserved) + - sizeof(ucmd.reserved); - if (udata->inlen < required_cmd_sz) - return -EINVAL; - - if (udata->inlen > sizeof(ucmd) && - !ib_is_udata_cleared(udata, sizeof(ucmd), - udata->inlen - sizeof(ucmd))) - return -EOPNOTSUPP; - - if (ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen))) - return -EFAULT; + err = ib_copy_validate_udata_in(udata, ucmd, reserved); + if (err) + return err; if (ucmd.comp_mask || ucmd.reserved) return -EOPNOTSUPP; diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 59f9ddb35d4620..d4d5e0d457a0b5 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -4707,17 +4707,9 @@ int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, return -ENOSYS; if (udata && udata->inlen) { - if (udata->inlen < offsetofend(typeof(ucmd), ece_options)) - return -EINVAL; - - if (udata->inlen > sizeof(ucmd) && - !ib_is_udata_cleared(udata, sizeof(ucmd), - udata->inlen - sizeof(ucmd))) - return -EOPNOTSUPP; - - if (ib_copy_from_udata(&ucmd, udata, - min(udata->inlen, sizeof(ucmd)))) - return -EFAULT; + err = ib_copy_validate_udata_in(udata, ucmd, ece_options); + if (err) + return err; if (ucmd.comp_mask & ~MLX5_IB_MODIFY_QP_OOO_DP || memchr_inv(&ucmd.burst_info.reserved, 0, @@ -5389,25 +5381,11 @@ static int prepare_user_rq(struct ib_pd *pd, struct mlx5_ib_dev *dev = to_mdev(pd->device); struct mlx5_ib_create_wq ucmd = {}; int err; - size_t required_cmd_sz; - - required_cmd_sz = offsetofend(struct mlx5_ib_create_wq, - single_stride_log_num_of_bytes); - if (udata->inlen < required_cmd_sz) { - mlx5_ib_dbg(dev, "invalid inlen\n"); - return -EINVAL; - } - - if (udata->inlen > sizeof(ucmd) && - !ib_is_udata_cleared(udata, sizeof(ucmd), - udata->inlen - sizeof(ucmd))) { - mlx5_ib_dbg(dev, "inlen is not supported\n"); - return -EOPNOTSUPP; - } - - if (ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen))) { + err = ib_copy_validate_udata_in(udata, ucmd, + single_stride_log_num_of_bytes); + if (err) { mlx5_ib_dbg(dev, "copy failed\n"); - return -EFAULT; + return err; } if (ucmd.comp_mask & (~MLX5_IB_CREATE_WQ_STRIDING_RQ)) { @@ -5626,7 +5604,6 @@ int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr, struct mlx5_ib_dev *dev = to_mdev(wq->device); struct mlx5_ib_rwq *rwq = to_mrwq(wq); struct mlx5_ib_modify_wq ucmd = {}; - size_t required_cmd_sz; int curr_wq_state; int wq_state; int inlen; @@ -5634,17 +5611,9 @@ int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr, void *rqc; void *in; - required_cmd_sz = offsetofend(struct mlx5_ib_modify_wq, reserved); - if (udata->inlen < required_cmd_sz) - return -EINVAL; - - if (udata->inlen > sizeof(ucmd) && - !ib_is_udata_cleared(udata, sizeof(ucmd), - udata->inlen - sizeof(ucmd))) - return -EOPNOTSUPP; - - if (ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen))) - return -EFAULT; + err = ib_copy_validate_udata_in(udata, ucmd, reserved); + if (err) + return err; if (ucmd.comp_mask || ucmd.reserved) return -EOPNOTSUPP; -- 2.43.0
