Re: Fw: Linux tcp_xmit_retransmit_queue use after free on 4.8-rc1 / master]
From: Cong Wang <hidden>
Date: 2016-08-16 20:19:36
On Tue, Aug 16, 2016 at 11:39 AM, Eric Dumazet [off-list ref] wrote:
quoted hunk ↗ jump to hunk
On Tue, 2016-08-16 at 08:39 -0700, Eric Dumazet wrote:quoted
On Tue, 2016-08-16 at 12:45 +0200, Greg KH wrote:quoted
For some reason Marco's emails can't make it to netdev, so I'm forwarding this on. Please cc: him on responses.Thanks for the report Greg and Marco. My first guess is this is caused by d41a69f1d390 tcp: make tcp_sendmsg() aware of socket backlog And a combination of funky sendmsg() flags (like FastOpen) I will look at this problem today.No, above commit was innocent ;) It looks like the bug is very old, and following patch would fix it. I will submit it formally after few tests.diff --git a/include/net/tcp.h b/include/net/tcp.h index c00e7d51bb18..7717302cab91 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h@@ -1523,6 +1523,8 @@ static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unli { if (sk->sk_send_head == skb_unlinked) sk->sk_send_head = NULL; + if (tcp_sk(sk)->highest_sack == skb_unlinked) + tcp_sk(sk)->highest_sack = NULL; }
Hmm, but from the stack traces it indicates the skb is freed
inside tcp_sendmsg(), which must be:
do_fault:
if (!skb->len) {
tcp_unlink_write_queue(skb, sk);
/* It is the one place in all of TCP, except connection
* reset, where we can be unlinking the send_head.
*/
tcp_check_send_head(sk, skb);
sk_wmem_free_skb(sk, skb);
}
In this case, skb->len == 0 means it is newly allocated skb by
sk_stream_alloc_skb(), so it should not have a chance to be
picked by tp->highest_sack yet b/c the whole function locks
the sock?
I must miss something here.