* [PATCH net v3] net/rds: ib: zero the unwritten tail of a short receive fragment
@ 2026-10-08 12:49 Shubham Antil
2026-10-08 12:53 ` netdev-bot+sinfo
2026-10-09 12:49 ` sashiko-bot
0 siblings, 2 replies; 3+ messages in thread
From: Shubham Antil @ 2026-10-08 12:49 UTC (permalink / raw)
To: netdev, linux-rdma
Cc: Allison Henderson, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, linux-kernel, Giovanni Vignone,
sungbyeongchan
rds_ib_process_recv() accepts an RDS/IB fragment once the receive
completion reports at least an RDS header, and then trusts the
header-declared message length h_len: rds_ib_inc_copy_to_user() later
copies up to h_len bytes from the fragment pages to userspace on
recvmsg().
When a fragment carries fewer payload bytes than h_len accounts for, the
bytes between the end of the received payload and h_len are read from the
unwritten tail of the fragment page. That page comes from the per-CPU
receive cache and is not zeroed, so recvmsg() returns stale page contents
to userspace.
Zero the unwritten tail of a short fragment page on receipt, so the copy
can only ever return received payload or zeros. Fragments that fill the
page are unaffected.
Confirmed under KMSAN: without this change recvmsg() returns stale
frag-page bytes and KMSAN flags an uninitialised copy in
rds_ib_inc_copy_to_user(); with it the same over-read returns zeros and
KMSAN is clean.
Fixes: 1e23b3ee0e94 ("RDS/IB: Receive datagrams via IB")
Reported-by: sungbyeongchan <tjdqudcks0424@naver.com>
Closes: https://lore.kernel.org/netdev/20261006205204.1322102-1-tjdqudcks0424@naver.com/
Reported-by: Shubham Antil <shubham@octane.security>
Reported-by: Giovanni Vignone <gio@octane.security>
Reported-by: Robert van Eijk <robert@octane.security>
Reported-by: Paolo Gentry <paolo@octane.security>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Shubham Antil <shubham@octane.security>
---
v3:
- Zero the unwritten fragment tail instead of dropping the connection.
A zero-copy send with a small iovec segment can legitimately produce a
non-final fragment shorter than RDS_FRAG_SIZE, so the v2 length check
could force a reconnect on well-formed traffic; zeroing the tail avoids
that while still keeping uninitialised bytes out of recvmsg().
(Raised by the Sashiko review.)
- Drop Reviewed-by, since the approach changed.
v2:
- Add Reported-by (sungbyeongchan, first to report, and the Octane
Security reporters).
net/rds/ib_recv.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index bd6cb3ffa..9695c7f24 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -35,6 +35,7 @@
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
+#include <linux/highmem.h>
#include <rdma/rdma_cm.h>
#include "rds_single_path.h"
@@ -949,6 +950,19 @@ static void rds_ib_process_recv(struct rds_connection *conn,
}
}
+ /* The device wrote only data_len bytes into this recycled fragment
+ * page. Zero the unwritten tail so a later rds_ib_inc_copy_to_user(),
+ * which copies up to the peer-declared h_len, cannot hand stale page
+ * contents to userspace.
+ */
+ if (data_len < RDS_FRAG_SIZE) {
+ void *frag = kmap_local_page(sg_page(&recv->r_frag->f_sg));
+
+ memset(frag + recv->r_frag->f_sg.offset + data_len, 0,
+ RDS_FRAG_SIZE - data_len);
+ kunmap_local(frag);
+ }
+
list_add_tail(&recv->r_frag->f_item, &ibinc->ii_frags);
recv->r_frag = NULL;
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH net v3] net/rds: ib: zero the unwritten tail of a short receive fragment
2026-10-08 12:49 [PATCH net v3] net/rds: ib: zero the unwritten tail of a short receive fragment Shubham Antil
@ 2026-10-08 12:53 ` netdev-bot+sinfo
2026-10-09 12:49 ` sashiko-bot
1 sibling, 0 replies; 3+ messages in thread
From: netdev-bot+sinfo @ 2026-10-08 12:53 UTC (permalink / raw)
To: Shubham Antil
Cc: netdev, linux-rdma, Allison Henderson, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
linux-kernel, Giovanni Vignone, sungbyeongchan
Hi!
This is an automated message. This series looks like a fix, but its
commit messages seem to be missing some information:
- How the issue was discovered, e.g. hit in production, hit during
development, syzbot report, manual code inspection, LLM or static
analysis tool scan.
Please do not repost the series just to address the above. Instead,
reply to this email with the missing information, so that reviewers
can take it into account. If the series needs another revision for
other reasons, please include the information in the commit messages
then.
The evaluation is done by an LLM so it may be wrong, if you think
that is the case please reply and explain.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net v3] net/rds: ib: zero the unwritten tail of a short receive fragment
2026-10-08 12:49 [PATCH net v3] net/rds: ib: zero the unwritten tail of a short receive fragment Shubham Antil
2026-10-08 12:53 ` netdev-bot+sinfo
@ 2026-10-09 12:49 ` sashiko-bot
1 sibling, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-10-09 12:49 UTC (permalink / raw)
To: Shubham Antil; +Cc: linux-rdma
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] rds: ib: zeroing short non-final fragments corrupts payload and desynchronizes framing
- [High] net/rds: unbounded memory allocation on receive via untrusted h_len
--
commit 155e0b4d269458cc1b33d64be6029fcc1b1efa50
Author: Shubham Antil <shubham@octane.security>
Subject: net/rds: ib: zero the unwritten tail of a short receive fragment
This commit zeroes the unwritten tail of short receive fragments to prevent
stale page contents from being copied to userspace. It attempts to resolve a
KMSAN uninitialized memory warning by ensuring the tail of the fragment is
zeroed before processing.
Closes: https://lore.kernel.org/netdev/20261006205204.1322102-1-tjdqudcks0424@naver.com/
> diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
> index bd6cb3ffaa571..9695c7f24eaa7 100644
> --- a/net/rds/ib_recv.c
> +++ b/net/rds/ib_recv.c
[ ... ]
> @@ -949,6 +950,19 @@ static void rds_ib_process_recv(struct rds_connection *conn,
> }
> }
>
[Severity: High]
Does this code allow unbounded memory allocation based on an untrusted header
field?
Earlier in rds_ib_process_recv(), the receiver extracts hdr->h_len from the
network and initializes ic->i_recv_data_rem:
net/rds/ib_recv.c:rds_ib_process_recv() {
...
memcpy(hdr, ihdr, sizeof(*hdr));
ic->i_recv_data_rem = be32_to_cpu(hdr->h_len);
...
}
It doesn't appear to validate it against RDS_MAX_MSG_SIZE. Can a malicious
remote peer stream data with a massive h_len to consume gigabytes of memory
per message and cause system exhaustion (OOM), especially since the same
unbounded h_len behavior appears to exist in TCP receive via
rds_tcp_data_recv()?
net/rds/tcp_recv.c:rds_tcp_data_recv() {
...
if (tc->t_tinc_hdr_rem == 0) {
/* could be 0 for a 0 len message */
tc->t_tinc_data_rem =
be32_to_cpu(tinc->ti_inc.i_hdr.h_len);
...
}
> + /* The device wrote only data_len bytes into this recycled fragment
> + * page. Zero the unwritten tail so a later rds_ib_inc_copy_to_user(),
> + * which copies up to the peer-declared h_len, cannot hand stale page
> + * contents to userspace.
> + */
> + if (data_len < RDS_FRAG_SIZE) {
> + void *frag = kmap_local_page(sg_page(&recv->r_frag->f_sg));
> +
> + memset(frag + recv->r_frag->f_sg.offset + data_len, 0,
> + RDS_FRAG_SIZE - data_len);
[Severity: High]
Can zeroing the unwritten tail here cause silent data corruption and
desynchronize the protocol framing?
The commit message explicitly states that a zero-copy send with a small iovec
segment can legitimately produce a non-final fragment shorter than
RDS_FRAG_SIZE. However, the receiver's framing logic statically assumes every
non-final fragment contains exactly RDS_FRAG_SIZE bytes:
net/rds/ib_recv.c:rds_ib_process_recv() {
...
if (ic->i_recv_data_rem > RDS_FRAG_SIZE)
ic->i_recv_data_rem -= RDS_FRAG_SIZE;
...
}
And the copy routine blindly copies up to RDS_FRAG_SIZE bytes from each
fragment without checking the actual received data_len:
net/rds/ib_recv.c:rds_ib_inc_copy_to_user() {
...
to_copy = min_t(unsigned long, iov_iter_count(to),
RDS_FRAG_SIZE - frag_off);
to_copy = min_t(unsigned long, to_copy, len - copied);
...
}
Doesn't this mean the zeroes injected by the patch are copied to userspace as
valid payload bytes, shifting and truncating the actual data instead of
correctly handling short non-final fragments?
> + kunmap_local(frag);
> + }
> +
> list_add_tail(&recv->r_frag->f_item, &ibinc->ii_frags);
> recv->r_frag = NULL;
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261008124940.13371-1-shubham@octane.security?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-09 12:49 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-08 12:49 [PATCH net v3] net/rds: ib: zero the unwritten tail of a short receive fragment Shubham Antil
2026-10-08 12:53 ` netdev-bot+sinfo
2026-10-09 12:49 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox