Fix NULL pointer dereference in tcp_nuke_addr.
authorLorenzo Colitti <lorenzo@google.com>
Mon, 14 Sep 2015 15:14:23 +0000 (00:14 +0900)
committerHuang, Tao <huangtao@rock-chips.com>
Tue, 27 Oct 2015 08:46:47 +0000 (16:46 +0800)
tcp_nuke addr only grabs the bottom half socket lock, but not the
userspace socket lock. This allows a userspace program to call
close() while the socket is running, which causes a NULL pointer
dereference in inet_put_port.

Bug: 23663111
Bug: 24072792
Change-Id: Iecb63af68c2db4764c74785153d1c9054f76b94f
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
(cherry picked from commit 74d66ee756afcc3269e4c1341f793c52be629af9)

net/ipv4/tcp.c

index 8cc9b54990138d882c2d74c5a751cd62999e3a66..72c04f7caf2bfc2bf0a71c727bb45192994e6ad1 100644 (file)
@@ -3568,14 +3568,17 @@ restart:
                        sock_hold(sk);
                        spin_unlock_bh(lock);
 
+                       lock_sock(sk);
+                       // TODO:
+                       // Check for SOCK_DEAD again, it could have changed.
+                       // Add a write barrier, see tcp_reset().
                        local_bh_disable();
-                       bh_lock_sock(sk);
                        sk->sk_err = ETIMEDOUT;
                        sk->sk_error_report(sk);
 
                        tcp_done(sk);
-                       bh_unlock_sock(sk);
                        local_bh_enable();
+                       release_sock(sk);
                        sock_put(sk);
 
                        goto restart;