[rds-devel] [External] : Re: [PATCH net] net/rds: fix tcp stream corruption with large pages

Allison Henderson achender at kernel.org
Sun Sep 6 14:44:01 UTC 2026


On Sat, 2026-09-05 at 10:00 -0700, Greg Marsden wrote:
> rds_message_map_pages() assigns PAGE_SIZE bytes to every
> scatterlist entry, even when total_len ends in a partial page. The RDS
> congestion map is defined as 8192 bytes, so on systems with PAGE_SIZE
> greater than 8192 the scatterlist maps bytes beyond the end of the
> congestion map.  RDS-TCP transmits the SG contents according to those
> lengths, so the extra bytes become part of the TCP RDS stream and are
> interpreted as subsequent RDS message headers, corrupting the stream.
> 
> Limit the final scatterlist mapping to the number of bytes remaining.
> This has no effect on systems with a 4K page size and allows RDS-TCP to
> be used on systems with 16K and larger page sizes.  
> 
> The RDS selftest, which previously hung on 16K pages, now passes.
> 
> Fixes: 7875e18e0996 ("RDS: Message parsing")
> Signed-off-by: Greg Marsden <greg.marsden at oracle.com>

Looks good, thanks for the catch!
Reviewed-by: Allison Henderson <achender at kernel.org>

> ---
>  net/rds/message.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/net/rds/message.c b/net/rds/message.c
> index f25f2592586f..47d5e9ab9b10 100644
> --- a/net/rds/message.c
> +++ b/net/rds/message.c
> @@ -431,7 +431,9 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in
>  	for (i = 0; i < rm->data.op_nents; ++i) {
>  		sg_set_page(&rm->data.op_sg[i],
>  				virt_to_page((void *)page_addrs[i]),
> -				PAGE_SIZE, 0);
> +				i == rm->data.op_nents - 1
> +					? total_len - (i * PAGE_SIZE)
> +					: PAGE_SIZE, 0);
>  	}
>  
>  	return rm;




More information about the rds-devel mailing list