The calculation for the remaining space, 'copy = size_goal - skb->len', was prone to an integer promotion bug that prevented copy from ever being negative. The variable types involved are: copy: ssize_t (long) size_goal: int skb->len: unsigned int Due to C's type promotion rules, the signed size_goal is converted to an unsigned int to match skb->len before the subtraction. The result is an unsigned int. When this unsigned int result is then assigned to the s64 copy variable, it is zero-extended, preserving its non-negative value. Consequently, copy is always >= 0. The intended logic is that a negative copy value indicates that the tail skb lacks sufficient space for appending new data, which should trigger the allocation of a new skb. Because of this bug, the condition copy <= 0 was never met, causing the code to always append to the tail skb. Fixes: 270a1c3de47e ("tcp: Support MSG_SPLICE_PAGES") Signed-off-by: Jiayuan Chen --- net/ipv4/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 8a3c99246d2e..ed942cd17351 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1180,7 +1180,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size) skb = tcp_write_queue_tail(sk); if (skb) - copy = size_goal - skb->len; + copy = size_goal - (ssize_t)skb->len; trace_tcp_sendmsg_locked(sk, msg, skb, size_goal); -- 2.47.1