inetpeer: fix race in unused_list manipulations
commitc9f1dcbe9f046d8840467395ba83dbfdd77bce65
authorEric Dumazet <eric.dumazet@gmail.com>
Thu, 26 May 2011 17:27:11 +0000 (26 17:27 +0000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Sat, 9 Jul 2011 06:14:53 +0000 (8 23:14 -0700)
treeaceaaa087ca4c12e9dacf20dd3a8a6bb8797e77d
parent335e781b640b24b9043319cbf5c8a131bee4d522
inetpeer: fix race in unused_list manipulations

[ Upstream commit 686a7e32ca7fdd819eb9606abd3db52b77d1479f ]

Several crashes in cleanup_once() were reported in recent kernels.

Commit d6cc1d642de9 (inetpeer: various changes) added a race in
unlink_from_unused().

One way to avoid taking unused_peers.lock before doing the list_empty()
test is to catch 0->1 refcnt transitions, using full barrier atomic
operations variants (atomic_cmpxchg() and atomic_inc_return()) instead
of previous atomic_inc() and atomic_add_unless() variants.

We then call unlink_from_unused() only for the owner of the 0->1
transition.

Add a new atomic_add_unless_return() static helper

With help from Arun Sharma.

Refs: https://bugzilla.kernel.org/show_bug.cgi?id=32772

Reported-by: Arun Sharma <asharma@fb.com>
Reported-by: Maximilian Engelhardt <maxi@daemonizer.de>
Reported-by: Yann Dupont <Yann.Dupont@univ-nantes.fr>
Reported-by: Denys Fedoryshchenko <denys@visp.net.lb>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
net/ipv4/inetpeer.c