linux-rdma.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Nicolas Morey" <nmorey@suse.com>
Cc: linux-rdma@vger.kernel.org
Subject: Re: [PATCH v2] RDMA/rxe: Use validated num_sge in local buffer
Date: Wed, 09 Sep 2026 16:21:34 +0000	[thread overview]
Message-ID: <20260909162134.EC4231F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260909160132.1491248-1-nmorey@suse.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [Critical] The receive WQE's DMA state fields (specifically `cur_sge`, `sge_offset`, `length`, and `resid`) are copied directly from shared user memory without validation or initialization. This leads to out-of-bounds array indexing and heap read/write in `copy_data()`.
- [Critical] The send path reads WQEs directly from the user-space shared ring buffer without making a local copy. All WQE fields, including `cur_sge`, `num_sge`, `sge_offset`, and `resid`, are subject to Time-Of-Check to Time-Of-Use (TOCTOU) races.
- [High] The local variable `num_sge` is read from shared user-memory `wqe->dma.num_sge` without using `READ_ONCE()`, creating a compiler double-fetch vulnerability between the bounds check and the `memcpy` size calculation.
--

commit 81af792b3b2b8089fc7af5abfac657516fe3ed47
Author: Nicolas Morey <nmorey@suse.com>

RDMA/rxe: Use validated num_sge in local buffer

This commit addresses a time-of-check to time-of-use heap overflow
in the receive path of rdma/rxe. It explicitly assigns the validated
num_sge to the locally copied wqe to prevent an attacker from modifying it
during the copy.

> diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
> index b1ea720aa34f9..ba3b2d23b36b7 100644
> --- a/drivers/infiniband/sw/rxe/rxe_resp.c
> +++ b/drivers/infiniband/sw/rxe/rxe_resp.c
> @@ -288,6 +288,7 @@ static enum resp_states get_srq_wqe(struct rxe_qp *qp)
>  	}
>  	size = sizeof(*wqe) + num_sge * sizeof(struct rxe_sge);
>  	memcpy(&qp->resp.srq_wqe, wqe, size);
> +	qp->resp.srq_wqe.wqe.dma.num_sge = num_sge;

[Severity: High]
This isn't a bug introduced by this patch, but does the read of num_sge
above this memcpy() in get_srq_wqe() require a READ_ONCE()?

	num_sge = wqe->dma.num_sge;
	if (unlikely(num_sge > srq->rq.max_sge)) {
		...
	}
	size = sizeof(*wqe) + num_sge * sizeof(struct rxe_sge);

Since wqe->dma.num_sge is in shared user-memory, can the compiler reload it
after the bounds check?

If an attacker modifies it concurrently in the shared mmap'd ring buffer,
could this result in an enormously large size calculation, causing memcpy()
to write far past the fixed-size local srq_wqe buffer into adjacent rxe_qp
fields?

[Severity: Critical]
This is a pre-existing issue, but are the other dma state fields like
cur_sge validated after being copied from shared memory here?

If an attacker crafts a wqe with an extremely large cur_sge, when
copy_data() in drivers/infiniband/sw/rxe/rxe_mr.c uses it as an array index:

	struct rxe_sge *sge = &dma->sge[dma->cur_sge];

could this result in an out-of-bounds kernel memory read past the local
srq_wqe structure and potential memory corruption?

>  
>  	qp->resp.wqe = &qp->resp.srq_wqe.wqe;
>  	queue_advance_consumer(q, QUEUE_TYPE_FROM_CLIENT);
> @@ -328,6 +329,7 @@ static enum resp_states rxe_get_recv_wqe(struct rxe_qp *qp)
>  	}
>  	size = sizeof(*wqe) + num_sge * sizeof(struct rxe_sge);
>  	memcpy(&qp->resp.srq_wqe, wqe, size);
> +	qp->resp.srq_wqe.wqe.dma.num_sge = num_sge;
>  
>  	qp->resp.wqe = &qp->resp.srq_wqe.wqe;
>  	return RESPST_CHK_LENGTH;

[Severity: Critical]
This is also a pre-existing issue, but does the send path have a similar
time-of-check to time-of-use vulnerability that should be addressed?

In drivers/infiniband/sw/rxe/rxe_req.c:rxe_requester(), num_sge and cur_sge
are checked directly against the shared ring buffer without making a local
copy:

	if (unlikely(wqe->dma.num_sge > qp->sq.max_sge ||
		     (wqe->dma.resid &&
		      wqe->dma.cur_sge >= qp->sq.max_sge))) {

Can an attacker thread modify cur_sge to a massive value immediately after
this check?

Later in rxe_req.c:finish_packet(), the shared memory wqe pointer is passed
directly to copy_data():

	err = copy_data(qp->pd, 0, &wqe->dma,
			payload_addr(pkt), payload,
			RXE_FROM_MR_OBJ);

which recalculates the array index from the unvalidated shared memory:

	struct rxe_sge *sge = &dma->sge[dma->cur_sge];

Could this cause an out-of-bounds array access beyond the vmalloc allocation
of the ring buffer?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260909160132.1491248-1-nmorey@suse.com?part=1

      reply	other threads:[~2026-09-09 16:21 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-09 16:01 [PATCH v2] RDMA/rxe: Use validated num_sge in local buffer Nicolas Morey
2026-09-09 16:21 ` sashiko-bot [this message]

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=20260909162134.EC4231F000FF@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=nmorey@suse.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /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;
as well as URLs for NNTP newsgroup(s).