From: Jacob Moroni <jmoroni@google.com>
To: tatyana.e.nikolova@intel.com, jgg@ziepe.ca, leon@kernel.org
Cc: linux-rdma@vger.kernel.org, Jacob Moroni <jmoroni@google.com>
Subject: [PATCH rdma-next 2/5] RDMA/irdma: Use robust udata input copy helpers
Date: Sat, 27 Jun 2026 02:56:39 +0000 [thread overview]
Message-ID: <20260627025642.4064973-3-jmoroni@google.com> (raw)
In-Reply-To: <20260627025642.4064973-1-jmoroni@google.com>
Replace the use of ib_copy_from_udata() with
ib_copy_validate_udata_in() where applicable.
For each modified call site, the last argument of
ib_copy_validate_udata_in() was determined by taking
the last member of the ABI struct as per its original
definition (i.e., when it was first committed).
Some methods like irdma_create_cq required special care
because the last member of the current ABI def is beyond
that of the legacy i40iw's ABI def which we need to
remain compatible with. In some other cases like modify_qp,
the legacy i40iw provider never provided any udata at all
so the validation is only performed if inlen > 0.
irdma_create_qp is more challenging because the legacy ABI
was actually larger but the additional fields were never used,
and even worse, never initialized in the provider. This will
be handled in a followup commit.
Signed-off-by: Jacob Moroni <jmoroni@google.com>
---
drivers/infiniband/hw/irdma/verbs.c | 61 +++++++++++++----------------
1 file changed, 27 insertions(+), 34 deletions(-)
diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
index e1c894fba2af..19dcc475c355 100644
--- a/drivers/infiniband/hw/irdma/verbs.c
+++ b/drivers/infiniband/hw/irdma/verbs.c
@@ -1554,10 +1554,13 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr,
if (iwqp->iwarp_state == IRDMA_QP_STATE_ERROR) {
iwqp->ibqp_state = attr->qp_state;
spin_unlock_irqrestore(&iwqp->lock, flags);
+ /* legacy i40iw does not send any udata. For
+ * current irdma, validate against ABI def.
+ */
if (udata && udata->inlen) {
- if (ib_copy_from_udata(&ureq, udata,
- min(sizeof(ureq), udata->inlen)))
- return -EINVAL;
+ ret = ib_copy_validate_udata_in(udata, ureq, rsvd);
+ if (ret)
+ return ret;
irdma_flush_wqes(iwqp,
(ureq.sq_flush ? IRDMA_FLUSH_SQ : 0) |
@@ -1758,9 +1761,9 @@ int irdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
iwqp->ibqp_state = attr->qp_state;
spin_unlock_irqrestore(&iwqp->lock, flags);
if (udata && udata->inlen) {
- if (ib_copy_from_udata(&ureq, udata,
- min(sizeof(ureq), udata->inlen)))
- return -EINVAL;
+ err = ib_copy_validate_udata_in(udata, ureq, rsvd);
+ if (err)
+ return err;
irdma_flush_wqes(iwqp,
(ureq.sq_flush ? IRDMA_FLUSH_SQ : 0) |
@@ -2033,7 +2036,6 @@ static int irdma_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
static int irdma_resize_cq(struct ib_cq *ibcq, unsigned 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;
@@ -2057,9 +2059,6 @@ static int irdma_resize_cq(struct ib_cq *ibcq, unsigned int entries,
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;
@@ -2089,9 +2088,9 @@ static int irdma_resize_cq(struct ib_cq *ibcq, unsigned int entries,
rdma_udata_to_drv_context(udata, struct irdma_ucontext,
ibucontext);
- if (ib_copy_from_udata(&req, udata,
- min(sizeof(req), udata->inlen)))
- return -EINVAL;
+ ret = ib_copy_validate_udata_in(udata, req, user_cq_buffer);
+ if (ret)
+ return ret;
spin_lock_irqsave(&ucontext->cq_reg_mem_list_lock, flags);
iwpbl_buf = irdma_get_pbl((unsigned long)req.user_cq_buffer,
@@ -2265,24 +2264,20 @@ static int irdma_setup_umode_srq(struct irdma_device *iwdev,
struct irdma_srq_init_info *info,
struct ib_udata *udata)
{
-#define IRDMA_CREATE_SRQ_MIN_REQ_LEN \
- offsetofend(struct irdma_create_srq_req, user_shadow_area)
struct irdma_create_srq_req req = {};
struct irdma_ucontext *ucontext;
struct irdma_srq_mr *srqmr;
struct irdma_pbl *iwpbl;
unsigned long flags;
+ int ret;
iwsrq->user_mode = true;
ucontext = rdma_udata_to_drv_context(udata, struct irdma_ucontext,
ibucontext);
- if (udata->inlen < IRDMA_CREATE_SRQ_MIN_REQ_LEN)
- return -EINVAL;
-
- if (ib_copy_from_udata(&req, udata,
- min(sizeof(req), udata->inlen)))
- return -EFAULT;
+ ret = ib_copy_validate_udata_in(udata, req, user_shadow_area);
+ if (ret)
+ return ret;
spin_lock_irqsave(&ucontext->srq_reg_mem_list_lock, flags);
iwpbl = irdma_get_pbl((unsigned long)req.user_srq_buf,
@@ -2487,7 +2482,6 @@ static int irdma_create_cq(struct ib_cq *ibcq,
const struct ib_cq_init_attr *attr,
struct uverbs_attr_bundle *attrs)
{
-#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_udata *udata = &attrs->driver_udata;
struct ib_device *ibdev = ibcq->device;
@@ -2511,8 +2505,7 @@ static int irdma_create_cq(struct ib_cq *ibcq,
if (err_code)
return err_code;
- if (udata && (udata->inlen < IRDMA_CREATE_CQ_MIN_REQ_LEN ||
- udata->outlen < IRDMA_CREATE_CQ_MIN_RESP_LEN))
+ if (udata && udata->outlen < IRDMA_CREATE_CQ_MIN_RESP_LEN)
return -EINVAL;
err_code = irdma_alloc_rsrc(rf, rf->allocated_cqs, rf->max_cq, &cq_num,
@@ -2554,11 +2547,14 @@ static int irdma_create_cq(struct ib_cq *ibcq,
ucontext =
rdma_udata_to_drv_context(udata, struct irdma_ucontext,
ibucontext);
- if (ib_copy_from_udata(&req, udata,
- min(sizeof(req), udata->inlen))) {
- err_code = -EFAULT;
+ /* Even though the last member of struct irdma_create_cq_req
+ * was always user_shadow_area, we need backwards compat with
+ * the legacy i40iw struct i40iw_ucreate_cq which stopped
+ * at user_cq_buffer.
+ */
+ err_code = ib_copy_validate_udata_in(udata, req, user_cq_buf);
+ if (err_code)
goto cq_free_rsrc;
- }
spin_lock_irqsave(&ucontext->cq_reg_mem_list_lock, flags);
iwpbl = irdma_get_pbl((unsigned long)req.user_cq_buf,
@@ -3541,7 +3537,6 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
struct ib_dmah *dmah,
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_mem_reg_req req = {};
struct ib_umem *region = NULL;
@@ -3554,9 +3549,6 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
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_va(pd->device, start, len, access);
if (IS_ERR(region)) {
@@ -3565,9 +3557,10 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
return (struct ib_mr *)region;
}
- if (ib_copy_from_udata(&req, udata, min(sizeof(req), udata->inlen))) {
+ err = ib_copy_validate_udata_in(udata, req, sq_pages);
+ if (err) {
ib_umem_release(region);
- return ERR_PTR(-EFAULT);
+ return ERR_PTR(err);
}
iwmr = irdma_alloc_iwmr(region, pd, virt, req.reg_type);
--
2.55.0.rc0.799.gd6f94ed593-goog
next prev parent reply other threads:[~2026-06-27 2:56 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-27 2:56 [PATCH rdma-next 0/5] RDMA/irdma: Adopt robust udata Jacob Moroni
2026-06-27 2:56 ` [PATCH rdma-next 1/5] RDMA/irdma: Enforce empty udata input for no-input ops Jacob Moroni
2026-06-27 2:56 ` Jacob Moroni [this message]
2026-06-27 2:56 ` [PATCH rdma-next 3/5] RDMA/irdma: Use ib_respond_empty_udata where applicable Jacob Moroni
2026-06-27 2:56 ` [PATCH rdma-next 4/5] RDMA/irdma: Use robust udata helper for QP creation Jacob Moroni
2026-06-27 2:56 ` [PATCH rdma-next 5/5] RDMA/irdma: Enable uverbs_robust_udata compliance flag Jacob Moroni
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260627025642.4064973-3-jmoroni@google.com \
--to=jmoroni@google.com \
--cc=jgg@ziepe.ca \
--cc=leon@kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=tatyana.e.nikolova@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox