mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Zhu Yanjun <yanjun.zhu@linux.dev>
To: Jiale Yao <yaojiale02@163.com>, Zhu Yanjun <zyjzyj2000@gmail.com>,
	Jason Gunthorpe <jgg@ziepe.ca>, Leon Romanovsky <leon@kernel.org>,
	Doug Ledford <dledford@redhat.com>,
	Moni Shoua <monis@mellanox.com>,
	Haggai Eran <haggaie@mellanox.com>,
	Kamal Heib <kamalh@mellanox.com>, Amir Vadai <amirv@mellanox.com>,
	linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org,
	"yanjun.zhu@linux.dev" <yanjun.zhu@linux.dev>
Subject: Re: [PATCH v3] RDMA/rxe: Validate inline data range in user WQEs
Date: Sun, 4 Oct 2026 17:29:42 -0700	[thread overview]
Message-ID: <009f918c-f77a-4b46-ab6d-96d81e1ed87d@linux.dev> (raw)
In-Reply-To: <20261004064445.1488753-1-yaojiale02@163.com>

在 2026/10/3 23:44, Jiale Yao 写道:
> For a user QP, the send queue is an mmap'd ring which userspace writes
> directly.  rxe_post_send() only schedules the send task for such a QP,
> so userspace can also change WQE fields while rxe_requester() processes
> the WQE.
> 
> Commit 126c757e4cd46f866ddc283143b58eb4d9bf52cd ("RDMA/rxe:
> Validate num_sge/cur_sge before indexing wqe->dma.sge[]") added bounds
> checks for two members of the userspace-controlled dma structure, but
> left sge_offset unchecked.  For an inline WQE, finish_packet() uses that
> value directly as an index into inline_data[] and copies dma.resid bytes
> from the resulting pointer into the packet payload.
> 
> A local user with access to uverbs can therefore put an out-of-range
> sge_offset in the mmap'd SQ ring.  This can disclose kernel memory in the
> outgoing packet or cause a vmalloc out-of-bounds access.
> 
> Since sge_offset comes from shared memory, validating it in
> rxe_requester() and then reading it again in finish_packet() leaves a
> TOCTOU window.  Load it exactly once with READ_ONCE() in finish_packet(),
> validate that local value, and use the same value for the copy and update.
> Check the offset first and use subtraction for the length check to avoid
> an integer overflow.
> 
> I reproduced this on Linux 7.3-rc4 with an RC user QP, IB_SEND_INLINE,
> a 64-byte residual length, and sge_offset set to 0x100000.  KASAN
> reported:
> 
>    BUG: KASAN: vmalloc-out-of-bounds in rxe_requester+0x1f27/0x4940
>    Read of size 64 at addr ffffc90000191250 by task kworker/u16:0/12
>    Workqueue: rxe_wq do_work
>    Call Trace:
>     __asan_memcpy
>     rxe_requester+0x1f27/0x4940
>     rxe_sender+0xe/0x30
>     do_work+0x184/0x3d0
>     process_scheduled_works+0x7c0/0xf10

Conceptually, wqe->dma.sge_offset is runtime state that should be 
exclusively managed by the kernel, but mapping the SQ into user space 
via mmap exposes it to untrusted asynchronous writes.

Beyond finish_packet(), every reader of sge_offset across the driver 
(such as in rxe_sge.c and rxe_resp.c) must treat it as untrusted input.

We should audit all access points to ensure they consistently use a 
READ_ONCE() local snapshot followed by underflow-safe bounds checks. 
Longer term, moving kernel-managed progress state into kernel-private 
memory would eliminate this attack surface entirely.

Yanjun Zhu

> 
> Fixes: 8700e3e7c485 ("Soft RoCE driver")
> Link: https://lore.kernel.org/all/20260708224534.1206-1-security@auditcode.ai/
> Signed-off-by: Jiale Yao <yaojiale02@163.com>
> ---
> 
> Notes:
>      Changes in v3:
>      - Read sge_offset from the shared WQE with READ_ONCE(), as requested.
>      
>      Changes in v2:
>      - Copy sge_offset into a local variable in finish_packet(), validate that
>        value, and reuse it for the memcpy and update.
> 
>   drivers/infiniband/sw/rxe/rxe_req.c | 14 +++++++++++---
>   1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
> index 24f5c044363f..9be753d2e5dd 100644
> --- a/drivers/infiniband/sw/rxe/rxe_req.c
> +++ b/drivers/infiniband/sw/rxe/rxe_req.c
> @@ -503,6 +503,7 @@ static int finish_packet(struct rxe_qp *qp, struct rxe_av *av,
>   			 struct sk_buff *skb, u32 payload)
>   {
>   	int err;
> +	u32 sge_offset;
>   
>   	err = rxe_prepare(av, pkt, skb);
>   	if (err)
> @@ -510,12 +511,19 @@ static int finish_packet(struct rxe_qp *qp, struct rxe_av *av,
>   
>   	if (pkt->mask & RXE_WRITE_OR_SEND_MASK) {
>   		if (wqe->wr.send_flags & IB_SEND_INLINE) {
> -			u8 *tmp = &wqe->dma.inline_data[wqe->dma.sge_offset];
> +			sge_offset = READ_ONCE(wqe->dma.sge_offset);
> +			if (unlikely(sge_offset > qp->sq.max_inline ||
> +				     payload >
> +				     qp->sq.max_inline - sge_offset)) {
> +				rxe_dbg_qp(qp, "invalid inline data range in send wqe\n");
> +				return -EINVAL;
> +			}
>   
> -			memcpy(payload_addr(pkt), tmp, payload);
> +			memcpy(payload_addr(pkt),
> +			       &wqe->dma.inline_data[sge_offset], payload);
>   
>   			wqe->dma.resid -= payload;
> -			wqe->dma.sge_offset += payload;
> +			wqe->dma.sge_offset = sge_offset + payload;
>   		} else {
>   			err = copy_data(qp->pd, 0, &wqe->dma,
>   					payload_addr(pkt), payload,


      reply	other threads:[~2026-10-05  0:29 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-04  6:44 Jiale Yao
2026-10-05  0:29 ` Zhu Yanjun [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=009f918c-f77a-4b46-ab6d-96d81e1ed87d@linux.dev \
    --to=yanjun.zhu@linux.dev \
    --cc=amirv@mellanox.com \
    --cc=dledford@redhat.com \
    --cc=haggaie@mellanox.com \
    --cc=jgg@ziepe.ca \
    --cc=kamalh@mellanox.com \
    --cc=leon@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=monis@mellanox.com \
    --cc=yaojiale02@163.com \
    --cc=zyjzyj2000@gmail.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

all inboxes | Powered by JetHome®