Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tcp: repair: fix TCP_QUEUE_SEQ implementation

When application uses TCP_QUEUE_SEQ socket option to
change tp->rcv_next, we must also update tp->copied_seq.

Otherwise, stuff relying on tcp_inq() being precise can
eventually be confused.

For example, tcp_zerocopy_receive() might crash because
it does not expect tcp_recv_skb() to return NULL.

We could add tests in various places to fix the issue,
or simply make sure tcp_inq() wont return a random value,
and leave fast path as it is.

Note that this fixes ioctl(fd, SIOCINQ, &val) at the same
time.

Fixes: ee9952831cfd ("tcp: Initial repair mode")
Fixes: 05255b823a61 ("tcp: add TCP_ZEROCOPY_RECEIVE support for zerocopy receive")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Eric Dumazet and committed by
David S. Miller
6cd6cbf5 83a9b6f6

+3 -1
+3 -1
net/ipv4/tcp.c
··· 2948 2948 err = -EPERM; 2949 2949 else if (tp->repair_queue == TCP_SEND_QUEUE) 2950 2950 WRITE_ONCE(tp->write_seq, val); 2951 - else if (tp->repair_queue == TCP_RECV_QUEUE) 2951 + else if (tp->repair_queue == TCP_RECV_QUEUE) { 2952 2952 WRITE_ONCE(tp->rcv_nxt, val); 2953 + WRITE_ONCE(tp->copied_seq, val); 2954 + } 2953 2955 else 2954 2956 err = -EINVAL; 2955 2957 break;