From: Dust Li <dust.li@linux.alibaba.com>
To: Ibrahim Hashimov <security@auditcode.ai>,
alibuda@linux.alibaba.com, wenjia@linux.ibm.com,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com
Cc: tonylu@linux.alibaba.com, guwen@linux.alibaba.com,
horms@kernel.org, linux-rdma@vger.kernel.org,
linux-s390@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH net] net/smc: validate peer CDC cursor against RMBE size before accepting it
Date: Wed, 22 Jul 2026 11:47:40 +0800 [thread overview]
Message-ID: <amA9XGOWH3z4Z1fu@linux.alibaba.com> (raw)
In-Reply-To: <20260720170717.11425-1-security@auditcode.ai>
On 2026-07-20 19:07:17, Ibrahim Hashimov wrote:
Hi Ibrahim,
I believe Bryam already sent a similar patch to the mailist and I have already
reviewed it.
https://lore.kernel.org/netdev/20260705-b4-disp-28a1bbca-v4-1-be089b98acc6@proton.me/
Best regards,
Dust
>smc_cdc_cursor_to_host() converts the wire-format producer/consumer
>cursor of an incoming CDC message into a host smc_host_cursor. It rejects
>a cursor that goes backwards, but never checks that the cursor's count is
>inside the buffer it indexes. Per smc_host_cursor ("an offset in an
>RMBE") and the invariant smc_curs_add() enforces for every local advance
>(0 <= count < size), a valid cursor count must be < size; the wire cursor
>is peer-controlled and was never checked against that.
>
>smcr_cdc_msg_to_host() accepts the producer and consumer cursors, and the
>unbounded value feeds smc_curs_diff() in smc_cdc_msg_recv_action(), which
>computes new->count - old->count without clamping against size. A peer
>that puts an out-of-range prod.count on the wire (e.g. 0x7fffffff) drives
>bytes_to_rcv far past rmb_desc->len -- the very invariant the comment
>above the atomic_add() claims but does not enforce.
>
>smc_rx_recvmsg() then trusts bytes_to_rcv as the amount of valid RMB
>data. Its first copy chunk is safely bounded by rmb_desc->len -
>cons.count, but the second chunk copies (copylen - chunk_len) bytes from
>offset 0, and copylen came from the inflated readable -- an out-of-bounds
>read of the RMB's backing (v)malloc allocation, copied straight to the
>receiving process via _copy_to_iter(). This is a remote kernel-memory
>disclosure driven by a malicious SMC-R peer, needing no local privilege
>on the victim. The same unbounded count also reaches
>smc_cdc_handle_urg_data_arrival() (base + urg_curs.count - 1) -- a
>second, narrower OOB read.
>
>Fix it where the wire cursor is accepted, mirroring the cursor-sanity
>idiom two lines above: reject any incoming cursor whose count is >= the
>size of the buffer it will index. smc_cdc_cursor_to_host() gains a size
>parameter; smcr_cdc_msg_to_host() passes conn->rmb_desc->len for the
>producer cursor and conn->peer_rmbe_size for the consumer cursor. This
>bounds it at its single origin instead of patching every downstream
>consumer. SMC-D (smcd_cdc_msg_to_host()) does not use this helper and is
>a separate, out-of-scope gap.
>
>Reproduced on a v6.19 KASAN kernel (SMC-Rv2 over soft-RoCE): a peer
>emitting prod.count=0x7fffffff triggers a vmalloc-out-of-bounds read in
>_copy_to_iter() via smc_rx_recvmsg(), returning ~960 KB of RMB-adjacent
>kernel heap to userspace; an in-range cursor transfers cleanly. With the
>fix the out-of-range cursor is dropped before it reaches
>conn->local_rx_ctrl.prod, and the reproducer returns rc=0 with no report.
>
>Fixes: 5f08318f617b ("smc: connection data control (CDC)")
>Cc: stable@vger.kernel.org
>Signed-off-by: Ibrahim Hashimov <security@auditcode.ai>
>Assisted-by: AuditCode-AI:2026.07
>---
> net/smc/smc_cdc.h | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)
>
>diff --git a/net/smc/smc_cdc.h b/net/smc/smc_cdc.h
>index 696cc11f2303..f07bbef47073 100644
>--- a/net/smc/smc_cdc.h
>+++ b/net/smc/smc_cdc.h
>@@ -221,6 +221,7 @@ static inline void smc_host_msg_to_cdc(struct smc_cdc_msg *peer,
>
> static inline void smc_cdc_cursor_to_host(union smc_host_cursor *local,
> union smc_cdc_cursor *peer,
>+ unsigned int size,
> struct smc_connection *conn)
> {
> union smc_host_cursor temp, old;
>@@ -235,6 +236,14 @@ static inline void smc_cdc_cursor_to_host(union smc_host_cursor *local,
> if ((old.wrap == temp.wrap) &&
> (old.count > temp.count))
> return;
>+ /* count is an offset into the RMBE and must always stay inside
>+ * it (see smc_curs_add()); the peer is untrusted, so reject an
>+ * out-of-range wire cursor the same way an out-of-order one is
>+ * already rejected above, instead of letting it drive
>+ * bytes_to_rcv / the urgent-byte offset past the buffer end
>+ */
>+ if (temp.count >= size)
>+ return;
> smc_curs_copy(local, &temp, conn);
> }
>
>@@ -246,8 +255,10 @@ static inline void smcr_cdc_msg_to_host(struct smc_host_cdc_msg *local,
> local->len = peer->len;
> local->seqno = ntohs(peer->seqno);
> local->token = ntohl(peer->token);
>- smc_cdc_cursor_to_host(&local->prod, &peer->prod, conn);
>- smc_cdc_cursor_to_host(&local->cons, &peer->cons, conn);
>+ smc_cdc_cursor_to_host(&local->prod, &peer->prod,
>+ conn->rmb_desc->len, conn);
>+ smc_cdc_cursor_to_host(&local->cons, &peer->cons,
>+ conn->peer_rmbe_size, conn);
> local->prod_flags = peer->prod_flags;
> local->conn_state_flags = peer->conn_state_flags;
> }
>--
>2.50.1 (Apple Git-155)
prev parent reply other threads:[~2026-07-22 3:47 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-20 17:07 [PATCH net] net/smc: validate peer CDC cursor against RMBE size before accepting it Ibrahim Hashimov
2026-07-21 17:08 ` sashiko-bot
2026-07-22 3:47 ` Dust Li [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=amA9XGOWH3z4Z1fu@linux.alibaba.com \
--to=dust.li@linux.alibaba.com \
--cc=alibuda@linux.alibaba.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=guwen@linux.alibaba.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=security@auditcode.ai \
--cc=stable@vger.kernel.org \
--cc=tonylu@linux.alibaba.com \
--cc=wenjia@linux.ibm.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.