On Thu, Oct 15, 2026 at 12:37 AM Octavian Purdila <[email protected]> wrote: > > When sk_wmem_schedule(sk, copy) fails under TCP memory pressure and > sk->sk_wmem_queued already reaches or exceeds sysctl_tcp_wmem[0], > tcp_wmem_schedule() returns min(copy, sk->sk_forward_alloc). > > However, sk->sk_forward_alloc is a signed int that can transiently > become negative when tcp_collapse() re-packs partially read or high > payload-to-truesize SKBs in the receive queue and charges newly > allocated SKBs via sk_mem_charge() before freeing the original SKB. > > If tcp_wmem_schedule() returns a negative value, tcp_sendmsg_locked() > passes that negative copy length to skb_copy_to_page_nocache() -> > copy_from_iter_full() -> check_copy_size(), where it is converted to an > unsigned size_t > INT_MAX, triggering a WARN_ON_ONCE(bytes > INT_MAX) > and returning -EFAULT instead of waiting for memory or returning > -EAGAIN. > > Clamp the return value of tcp_wmem_schedule() to [0, copy] so callers > treat negative sk_forward_alloc as 0 available bytes. > > Fixes: 849b425cd091 ("tcp: fix possible freeze in tx path under memory > pressure") > Assisted-by: LLM > Signed-off-by: Octavian Purdila <[email protected]>
Reviewed-by: Kuniyuki Iwashima <[email protected]> Basically sk->sk_forward_alloc should not be negative, and I was able to avoid that by refactoring tcp_collapse(), but it was a bit invasive for stable and late in rc8, so I'll post it in the next cycle. $ git diff --stat HEAD~4 net/ipv4/tcp_input.c | 158 ... 1 file changed, 109 insertions(+), 49 deletions(-)

