diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-12-23 09:32:46 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-12-23 09:32:46 -0800 |
commit | 1bde5ac49398a064c753bb490535cfad89e99a5f (patch) | |
tree | 9a26c9da2be8e1a6eedc089dd7719e14ac9b184b | |
parent | b7e03ec9a6b9d0c0cb1e435026d46dfcd78e48ac (diff) | |
download | lwn-1bde5ac49398a064c753bb490535cfad89e99a5f.tar.gz lwn-1bde5ac49398a064c753bb490535cfad89e99a5f.zip |
tcp: fix listening_get_next()
Alexey Vlasov found /proc/net/tcp could sometime loop and display
millions of sockets in LISTEN state.
In 2.6.29, when we converted TCP hash tables to RCU, we left two
sk_next() calls in listening_get_next().
We must instead use sk_nulls_next() to properly detect an end of chain.
Reported-by: Alexey Vlasov <renton@renton.name>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index e13da6de1fc7..d978bb2f748b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2030,7 +2030,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur) get_req: req = icsk->icsk_accept_queue.listen_opt->syn_table[st->sbucket]; } - sk = sk_next(st->syn_wait_sk); + sk = sk_nulls_next(st->syn_wait_sk); st->state = TCP_SEQ_STATE_LISTENING; read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); } else { @@ -2039,7 +2039,7 @@ get_req: if (reqsk_queue_len(&icsk->icsk_accept_queue)) goto start_req; read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); - sk = sk_next(sk); + sk = sk_nulls_next(sk); } get_sk: sk_nulls_for_each_from(sk, node) { |