Re: [PATCH net] net: Avoid checksumming unreadable skb tail on trim
From: Breno Leitao
Date: Fri May 22 2026 - 11:46:01 EST
On Fri, May 22, 2026 at 02:06:40PM +0200, Björn Töpel wrote:
> pskb_trim_rcsum_slow() keeps CHECKSUM_COMPLETE valid by subtracting
> the checksum of the bytes removed from the skb tail. That assumes the
> removed bytes can be read.
>
> io_uring zcrx skbs may contain unreadable net_iov frags. With fbnic
> header/data split, small TCP/IPv4 packets can carry Ethernet padding
> in such a frag. ip_rcv_core() trims the skb to iph->tot_len before TCP
> sees it, and the CHECKSUM_COMPLETE adjustment then calls
> skb_checksum() on the padding.
>
> This is exposed by IPv4 because small TCP/IPv4 frames can be shorter
> than the Ethernet minimum payload. TCP/IPv6 frames are large enough in
> the normal zcrx path, so they do not hit the same padding trim.
>
> Keep the existing checksum adjustment for readable skbs. If the
> remaining packet is fully linear, drop CHECKSUM_COMPLETE and let the
> stack validate the packet after trimming. If unreadable payload would
> remain, fail the trim; the checksum cannot be adjusted without reading
> the trimmed tail.
>
> Also clear skb->unreadable when trimming removes all frags.
>
> Fixes: 65249feb6b3d ("net: add support for skbs with unreadable frags")
> Signed-off-by: Björn Töpel <bjorn@xxxxxxxxxx>
Reviewed-by: Breno Leitao <leitao@xxxxxxxxxx>
> +static int pskb_trim_rcsum_complete(struct sk_buff *skb, unsigned int len)
> +{
> + int delta = skb->len - len;
I suppose this is not unsigned/size_t because csum_block_sub() requires
an 'int', is this right?
> /* Note : use pskb_trim_rcsum() instead of calling this directly
> */
I think you can make this a one-line comment, or just a proper kdoc.