From: Hidayath Khan <hidayath@linux.ibm.com>
To: alibuda@linux.alibaba.com, dust.li@linux.alibaba.com,
sidraya@linux.ibm.com, mjambigi@linux.ibm.com,
andrew+netdev@lunn.ch
Cc: tonylu@linux.alibaba.com, guwen@linux.alibaba.com,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, horms@kernel.org, pasic@linux.ibm.com,
hidayath@linux.ibm.com, linux-s390@vger.kernel.org,
netdev@vger.kernel.org
Subject: [PATCH net-next] net/smc: abort the connection when the peer overruns the RMB
Date: Tue, 4 Aug 2026 16:11:09 +0200 [thread overview]
Message-ID: <20260804141109.542202-1-hidayath@linux.ibm.com> (raw)
smc_cdc_msg_recv_action() accumulates the peer's producer cursor advance
into conn->bytes_to_rcv:
atomic_add(diff_prod, &conn->bytes_to_rcv);
/* guarantee 0 <= bytes_to_rcv <= rmb_desc->len */
Nothing enforces that comment. A conforming peer cannot advance its
producer cursor past our consumer cursor, so a peer that does fills the
accumulator without bound.
Bounding the cursor does not help: a wrap increment with count 0 is a legal
advance of exactly one bufferful, so every per-cursor check accepts it
while smc_curs_diff() returns size for each such message.
The copy-length clamps bound the copy but never repair the counter, so
SIOCINQ reports a readable length that does not exist and
smc_rx_data_available() keeps poll() readable forever with nothing for
recvmsg() to return.
Drop the connection instead, reusing the abort smc_cdc_msg_validate()
performs for an out-of-range sequence number. The test precedes the
atomic_add() so the counter is never left inflated; abandoning the rest of
the message matches smc_cdc_msg_validate(), and abort_work tears the
connection down.
The test is written as a subtraction. diff_prod is not bounded by the RMB:
smc_curs_diff() documents "difference cannot exceed size" as an assumption
about its inputs, but the peer controls the cursor it is computed from, so
it can return up to INT_MAX. Adding that to bytes_to_rcv would overflow
and the comparison would then read as false, defeating the check in exactly
the case it exists for. Subtracting cannot overflow, since bytes_to_rcv is
in [0, rmb_desc->len].
Both transports are affected: the accumulator is shared.
Reviewed-by: Sidraya Jayagond <sidraya@linux.ibm.com>
Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Signed-off-by: Hidayath Khan <hidayath@linux.ibm.com>
---
net/smc/smc_cdc.c | 39 ++++++++++++++++++++++++++++-----------
1 file changed, 28 insertions(+), 11 deletions(-)
diff --git a/net/smc/smc_cdc.c b/net/smc/smc_cdc.c
index 32d6d03df321..d8f747bbc6f6 100644
--- a/net/smc/smc_cdc.c
+++ b/net/smc/smc_cdc.c
@@ -305,6 +305,27 @@ static void smc_cdc_handle_urg_data_arrival(struct smc_sock *smc,
sk_send_sigurg(&smc->sk);
}
+/* Drop a connection whose peer violated the CDC protocol. @link is the link
+ * the offending message arrived on, or NULL when it is not known to the caller
+ * (SMC-D, and the shared receive path). When @link is NULL conn->lnk is left
+ * unchanged: for SMC-R it already points to the right QP; for SMC-D there is
+ * no per-link QP to abort on.
+ */
+static void smc_cdc_abort_conn(struct smc_sock *smc, struct smc_link *link)
+{
+ struct smc_connection *conn = &smc->conn;
+
+ conn->out_of_sync = 1; /* prevent any further receives */
+ spin_lock_bh(&conn->send_lock);
+ conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
+ if (link)
+ conn->lnk = link;
+ spin_unlock_bh(&conn->send_lock);
+ sock_hold(&smc->sk); /* sock_put in abort_work */
+ if (!queue_work(smc_close_wq, &conn->abort_work))
+ sock_put(&smc->sk);
+}
+
static void smc_cdc_msg_validate(struct smc_sock *smc, struct smc_cdc_msg *cdc,
struct smc_link *link)
{
@@ -314,17 +335,8 @@ static void smc_cdc_msg_validate(struct smc_sock *smc, struct smc_cdc_msg *cdc,
/* check that seqnum was seen before */
diff = conn->local_rx_ctrl.seqno - recv_seq;
- if (diff < 0) { /* diff larger than 0x7fff */
- /* drop connection */
- conn->out_of_sync = 1; /* prevent any further receives */
- spin_lock_bh(&conn->send_lock);
- conn->local_tx_ctrl.conn_state_flags.peer_conn_abort = 1;
- conn->lnk = link;
- spin_unlock_bh(&conn->send_lock);
- sock_hold(&smc->sk); /* sock_put in abort_work */
- if (!queue_work(smc_close_wq, &conn->abort_work))
- sock_put(&smc->sk);
- }
+ if (diff < 0) /* diff larger than 0x7fff */
+ smc_cdc_abort_conn(smc, link); /* drop connection */
}
static void smc_cdc_msg_recv_action(struct smc_sock *smc,
@@ -376,6 +388,11 @@ static void smc_cdc_msg_recv_action(struct smc_sock *smc,
diff_prod = smc_curs_diff(conn->rmb_desc->len, &prod_old,
&conn->local_rx_ctrl.prod);
if (diff_prod) {
+ if (diff_prod > conn->rmb_desc->len -
+ atomic_read(&conn->bytes_to_rcv)) {
+ smc_cdc_abort_conn(smc, NULL);
+ return;
+ }
if (conn->local_rx_ctrl.prod_flags.urg_data_present)
smc_cdc_handle_urg_data_arrival(smc, &diff_prod);
/* bytes_to_rcv is decreased in smc_recvmsg */
base-commit: cd138abf911f7a6b19656e446b09cff4453d1f3d
--
2.52.0
next reply other threads:[~2026-08-04 14:11 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-04 14:11 Hidayath Khan [this message]
2026-08-05 14:12 ` [PATCH net-next] net/smc: abort the connection when the peer overruns the RMB sashiko-bot
2026-08-05 16:03 ` Simon Horman
2026-08-07 15:36 ` Hidayathulla Khan I
-- strict thread matches above, loose matches on Subject: below --
2026-08-08 8:12 Bryam Vargas
2026-08-11 17:39 ` Hidayath Khan
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=20260804141109.542202-1-hidayath@linux.ibm.com \
--to=hidayath@linux.ibm.com \
--cc=alibuda@linux.alibaba.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=dust.li@linux.alibaba.com \
--cc=edumazet@google.com \
--cc=guwen@linux.alibaba.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=mjambigi@linux.ibm.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=pasic@linux.ibm.com \
--cc=sidraya@linux.ibm.com \
--cc=tonylu@linux.alibaba.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.