Re: sctp_close/sk_free: kernel BUG at arch/x86/mm/physaddr.c:18!
From: Jerry Chu <hidden>
Date: 2012-09-05 23:07:09
Also in:
netdev
On Wed, Sep 5, 2012 at 3:28 PM, Fengguang Wu [off-list ref] wrote:
On Wed, Sep 05, 2012 at 06:57:00PM +0200, Eric Dumazet wrote:quoted
On Wed, 2012-09-05 at 17:40 +0200, Eric Dumazet wrote:quoted
Could you test the following patch please ?It works - no single error for 1000 boots!
Sorry for introducing the bug, one of the casualties dealing with code that is shared outside of TCP. I did spend some effort adding special checks but I was wrong in assuming inet_create() will zero all the field including fastopenq inside icsk_accept_queue inside struct inet_connection_sock - although this is true for TCP and DCCP, SCTP doesn't have inet_connection_sock hence inet_csk(sk) is bogus. Kudo to Eric for fixing it quickly before I got to it. Jerry
btw, the first bad commit has been bisected to commit 8336886f786fdacbc19b719c1f7ea91eb70706d4 Author: Jerry Chu [off-list ref] Date: Fri Aug 31 12:29:12 2012 +0000 tcp: TCP Fast Open Server - support TFO listenersquoted
quoted
(Not sure why sctp doesnt memset/bzero its whole socket by the way...) ThanksHere is a more complete patch, as there are three potential problems, not only one :Great! I'll start tests for it. Thanks, Fengguangquoted
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 4f70ef0..845372b 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c@@ -149,11 +149,8 @@ void inet_sock_destruct(struct sock *sk) pr_err("Attempt to release alive inet socket %p\n", sk); return; } - if (sk->sk_type == SOCK_STREAM) { - struct fastopen_queue *fastopenq = - inet_csk(sk)->icsk_accept_queue.fastopenq; - kfree(fastopenq); - } + if (sk->sk_protocol == IPPROTO_TCP) + kfree(inet_csk(sk)->icsk_accept_queue.fastopenq); WARN_ON(atomic_read(&sk->sk_rmem_alloc)); WARN_ON(atomic_read(&sk->sk_wmem_alloc));diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 8464b79..f0c5b9c 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c@@ -314,7 +314,7 @@ struct sock *inet_csk_accept(struct sock *sk, int flags, int *err) newsk = req->sk; sk_acceptq_removed(sk); - if (sk->sk_type == SOCK_STREAM && queue->fastopenq != NULL) { + if (sk->sk_protocol == IPPROTO_TCP && queue->fastopenq != NULL) { spin_lock_bh(&queue->fastopenq->lock); if (tcp_rsk(req)->listener) { /* We are still waiting for the final ACK from 3WHS@@ -775,7 +775,7 @@ void inet_csk_listen_stop(struct sock *sk) percpu_counter_inc(sk->sk_prot->orphan_count); - if (sk->sk_type == SOCK_STREAM && tcp_rsk(req)->listener) { + if (sk->sk_protocol == IPPROTO_TCP && tcp_rsk(req)->listener) { BUG_ON(tcp_sk(child)->fastopen_rsk != req); BUG_ON(sk != tcp_rsk(req)->listener);-- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html