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);
-       struct irdma_alloc_ucontext_req req;
+       struct irdma_alloc_ucontext_req req = {};
        struct irdma_alloc_ucontext_resp uresp = {};
        struct irdma_ucontext *ucontext = to_ucontext(uctx);
        struct irdma_uk_attrs *uk_attrs;
 
+       if (udata->inlen < IRDMA_ALLOC_UCTX_MIN_REQ_LEN ||
+           udata->outlen < IRDMA_ALLOC_UCTX_MIN_RESP_LEN)
+               return -EINVAL;
+
        if (ib_copy_from_udata(&req, udata, min(sizeof(req), udata->inlen)))
                return -EINVAL;
 
 
        uk_attrs = &iwdev->rf->sc_dev.hw_attrs.uk_attrs;
        /* GEN_1 legacy support with libi40iw */
-       if (udata->outlen < sizeof(uresp)) {
+       if (udata->outlen == IRDMA_ALLOC_UCTX_MIN_RESP_LEN) {
                if (uk_attrs->hw_rev != IRDMA_GEN_1)
                        return -EOPNOTSUPP;
 
  */
 static int irdma_alloc_pd(struct ib_pd *pd, struct ib_udata *udata)
 {
+#define IRDMA_ALLOC_PD_MIN_RESP_LEN offsetofend(struct irdma_alloc_pd_resp, rsvd)
        struct irdma_pd *iwpd = to_iwpd(pd);
        struct irdma_device *iwdev = to_iwdev(pd->device);
        struct irdma_sc_dev *dev = &iwdev->rf->sc_dev;
        u32 pd_id = 0;
        int err;
 
+       if (udata && udata->outlen < IRDMA_ALLOC_PD_MIN_RESP_LEN)
+               return -EINVAL;
+
        err = irdma_alloc_rsrc(rf, rf->allocated_pds, rf->max_pd, &pd_id,
                               &rf->next_pd);
        if (err)
                           struct ib_qp_init_attr *init_attr,
                           struct ib_udata *udata)
 {
+#define IRDMA_CREATE_QP_MIN_REQ_LEN offsetofend(struct irdma_create_qp_req, user_compl_ctx)
+#define IRDMA_CREATE_QP_MIN_RESP_LEN offsetofend(struct irdma_create_qp_resp, rsvd)
        struct ib_pd *ibpd = ibqp->pd;
        struct irdma_pd *iwpd = to_iwpd(ibpd);
        struct irdma_device *iwdev = to_iwdev(ibpd->device);
        struct irdma_pci_f *rf = iwdev->rf;
        struct irdma_qp *iwqp = to_iwqp(ibqp);
-       struct irdma_create_qp_req req;
+       struct irdma_create_qp_req req = {};
        struct irdma_create_qp_resp uresp = {};
        u32 qp_num = 0;
        int err_code;
        if (err_code)
                return err_code;
 
+       if (udata && (udata->inlen < IRDMA_CREATE_QP_MIN_REQ_LEN ||
+                     udata->outlen < IRDMA_CREATE_QP_MIN_RESP_LEN))
+               return -EINVAL;
+
        sq_size = init_attr->cap.max_send_wr;
        rq_size = init_attr->cap.max_recv_wr;
 
 int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                         int attr_mask, struct ib_udata *udata)
 {
+#define IRDMA_MODIFY_QP_MIN_REQ_LEN offsetofend(struct irdma_modify_qp_req, rq_flush)
+#define IRDMA_MODIFY_QP_MIN_RESP_LEN offsetofend(struct irdma_modify_qp_resp, push_valid)
        struct irdma_pd *iwpd = to_iwpd(ibqp->pd);
        struct irdma_qp *iwqp = to_iwqp(ibqp);
        struct irdma_device *iwdev = iwqp->iwdev;
        roce_info = &iwqp->roce_info;
        udp_info = &iwqp->udp_info;
 
+       if (udata) {
+               /* udata inlen/outlen can be 0 when supporting legacy libi40iw */
+               if ((udata->inlen && udata->inlen < IRDMA_MODIFY_QP_MIN_REQ_LEN) ||
+                   (udata->outlen && udata->outlen < IRDMA_MODIFY_QP_MIN_RESP_LEN))
+                       return -EINVAL;
+       }
+
        if (attr_mask & ~IB_QP_ATTR_STANDARD_BITS)
                return -EOPNOTSUPP;
 
 
                        if (iwqp->iwarp_state == IRDMA_QP_STATE_ERROR) {
                                spin_unlock_irqrestore(&iwqp->lock, flags);
-                               if (udata) {
+                               if (udata && udata->inlen) {
                                        if (ib_copy_from_udata(&ureq, udata,
                                            min(sizeof(ureq), udata->inlen)))
                                                return -EINVAL;
                } else {
                        iwqp->ibqp_state = attr->qp_state;
                }
-               if (udata && dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) {
+               if (udata && udata->outlen && dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) {
                        struct irdma_ucontext *ucontext;
 
                        ucontext = rdma_udata_to_drv_context(udata,
 int irdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
                    struct ib_udata *udata)
 {
+#define IRDMA_MODIFY_QP_MIN_REQ_LEN offsetofend(struct irdma_modify_qp_req, rq_flush)
+#define IRDMA_MODIFY_QP_MIN_RESP_LEN offsetofend(struct irdma_modify_qp_resp, push_valid)
        struct irdma_qp *iwqp = to_iwqp(ibqp);
        struct irdma_device *iwdev = iwqp->iwdev;
        struct irdma_sc_dev *dev = &iwdev->rf->sc_dev;
        int err;
        unsigned long flags;
 
+       if (udata) {
+               /* udata inlen/outlen can be 0 when supporting legacy libi40iw */
+               if ((udata->inlen && udata->inlen < IRDMA_MODIFY_QP_MIN_REQ_LEN) ||
+                   (udata->outlen && udata->outlen < IRDMA_MODIFY_QP_MIN_RESP_LEN))
+                       return -EINVAL;
+       }
+
        if (attr_mask & ~IB_QP_ATTR_STANDARD_BITS)
                return -EOPNOTSUPP;
 
                case IB_QPS_RESET:
                        if (iwqp->iwarp_state == IRDMA_QP_STATE_ERROR) {
                                spin_unlock_irqrestore(&iwqp->lock, flags);
-                               if (udata) {
+                               if (udata && udata->inlen) {
                                        if (ib_copy_from_udata(&ureq, udata,
                                            min(sizeof(ureq), udata->inlen)))
                                                return -EINVAL;
                        }
                }
        }
-       if (attr_mask & IB_QP_STATE && udata &&
+       if (attr_mask & IB_QP_STATE && udata && udata->outlen &&
            dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) {
                struct irdma_ucontext *ucontext;
 
 static int irdma_resize_cq(struct ib_cq *ibcq, int entries,
                           struct ib_udata *udata)
 {
+#define IRDMA_RESIZE_CQ_MIN_REQ_LEN offsetofend(struct irdma_resize_cq_req, user_cq_buffer)
        struct irdma_cq *iwcq = to_iwcq(ibcq);
        struct irdma_sc_dev *dev = iwcq->sc_cq.dev;
        struct irdma_cqp_request *cqp_request;
            IRDMA_FEATURE_CQ_RESIZE))
                return -EOPNOTSUPP;
 
+       if (udata && udata->inlen < IRDMA_RESIZE_CQ_MIN_REQ_LEN)
+               return -EINVAL;
+
        if (entries > rf->max_cqe)
                return -EINVAL;
 
                           const struct ib_cq_init_attr *attr,
                           struct ib_udata *udata)
 {
+#define IRDMA_CREATE_CQ_MIN_REQ_LEN offsetofend(struct irdma_create_cq_req, user_cq_buf)
+#define IRDMA_CREATE_CQ_MIN_RESP_LEN offsetofend(struct irdma_create_cq_resp, cq_size)
        struct ib_device *ibdev = ibcq->device;
        struct irdma_device *iwdev = to_iwdev(ibdev);
        struct irdma_pci_f *rf = iwdev->rf;
        err_code = cq_validate_flags(attr->flags, dev->hw_attrs.uk_attrs.hw_rev);
        if (err_code)
                return err_code;
+
+       if (udata && (udata->inlen < IRDMA_CREATE_CQ_MIN_REQ_LEN ||
+                     udata->outlen < IRDMA_CREATE_CQ_MIN_RESP_LEN))
+               return -EINVAL;
+
        err_code = irdma_alloc_rsrc(rf, rf->allocated_cqs, rf->max_cq, &cq_num,
                                    &rf->next_cq);
        if (err_code)
                                       u64 virt, int access,
                                       struct ib_udata *udata)
 {
+#define IRDMA_MEM_REG_MIN_REQ_LEN offsetofend(struct irdma_mem_reg_req, sq_pages)
        struct irdma_device *iwdev = to_iwdev(pd->device);
        struct irdma_ucontext *ucontext;
        struct irdma_pble_alloc *palloc;
        if (len > iwdev->rf->sc_dev.hw_attrs.max_mr_size)
                return ERR_PTR(-EINVAL);
 
+       if (udata->inlen < IRDMA_MEM_REG_MIN_REQ_LEN)
+               return ERR_PTR(-EINVAL);
+
        region = ib_umem_get(pd->device, start, len, access);
 
        if (IS_ERR(region)) {
                                struct rdma_ah_init_attr *attr,
                                struct ib_udata *udata)
 {
+#define IRDMA_CREATE_AH_MIN_RESP_LEN offsetofend(struct irdma_create_ah_resp, rsvd)
        struct irdma_ah *ah = container_of(ibah, struct irdma_ah, ibah);
        struct irdma_device *iwdev = to_iwdev(ibah->pd->device);
        struct irdma_create_ah_resp uresp;
        struct irdma_ah *parent_ah;
        int err;
 
+       if (udata && udata->outlen < IRDMA_CREATE_AH_MIN_RESP_LEN)
+               return -EINVAL;
+
        err = irdma_setup_ah(ibah, attr);
        if (err)
                return err;