When the device can't checksum the protocol, skb_segment() checksums each segment with skb_checksum(). If the segment has unreadable frags, or its lengths don't add up, skb_checksum() returns 0 and the segment goes out with a checksum that doesn't cover its payload. Devmem TCP doesn't get that far today. Its skbs take SKBFL_SHARED_FRAG from the zerocopy uarg, so skb_segment() tries to linearize the segment first, and that fails with -ENOMEM for unreadable frags. No other path is known to bring an unreadable segment here either. Use skb_checksum_full() and fail the segmentation with -EFAULT, so that the checksum doesn't depend on that flag. Found by the Sashiko AI review of an earlier fix for the same path with SG off. Link: https://lore.kernel.org/all/20261009-b4-skb-segment-nosg-unreadable-v1-1-7e2334a55fe8@toxicpanda.com/ Reviewed-by: Fernando Fernandez Mancera Signed-off-by: Josef Bacik --- net/core/skbuff.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 0d3f0f09c7d1..5f997edf3519 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -5292,9 +5292,13 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb, if (!nskb->remcsum_offload) nskb->ip_summed = CHECKSUM_NONE; - SKB_GSO_CB(nskb)->csum = - skb_checksum(nskb, doffset, - nskb->len - doffset, 0); + SKB_GSO_CB(nskb)->csum = 0; + if (skb_checksum_full(nskb, doffset, + nskb->len - doffset, + &SKB_GSO_CB(nskb)->csum)) { + err = -EFAULT; + goto err; + } SKB_GSO_CB(nskb)->csum_start = skb_headroom(nskb) + doffset; } -- 2.55.0