net: fix NULL dereferences in check_peer_redir()
authorEric Dumazet <eric.dumazet@gmail.com>
Thu, 9 Feb 2012 21:13:19 +0000 (16:13 -0500)
committerbuildbot <buildbot@intel.com>
Sat, 5 May 2012 01:38:29 +0000 (18:38 -0700)
commitc6a161647fdb86e8d61ae904bc4afee6f0563a10
treefeb7e42df5cf8d05706f98dd03bb61e3fadcfba7
parent7cfcc99329600f37a4fbf0a4cc9540452e3f0235
net: fix NULL dereferences in check_peer_redir()

BZ: 33030

[ Upstream commit d3aaeb38c40e5a6c08dd31a1b64da65c4352be36, along
  with dependent backports of commits:
     69cce1d1404968f78b177a0314f5822d5afdbbfb
     9de79c127cccecb11ae6a21ab1499e87aa222880
     218fa90f072e4aeff9003d57e390857f4f35513e
     580da35a31f91a594f3090b7a2c39b85cb051a12
     f7e57044eeb1841847c24aa06766c8290c202583
     e049f28883126c689cf95859480d9ee4ab23b7fa ]

Gergely Kalman reported crashes in check_peer_redir().

It appears commit f39925dbde778 (ipv4: Cache learned redirect
information in inetpeer.) added a race, leading to possible NULL ptr
dereference.

Since we can now change dst neighbour, we should make sure a reader can
safely use a neighbour.

Add RCU protection to dst neighbour, and make sure check_peer_redir()
can be called safely by different cpus in parallel.

As neighbours are already freed after one RCU grace period, this patch
should not add typical RCU penalty (cache cold effects)

Many thanks to Gergely for providing a pretty report pointing to the
bug.

Reported-by: Gergely Kalman <synapse@hippy.csoma.elte.hu>
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@linuxfoundation.org>
Change-Id: Ife70cefaf6741e7b958901fae83521efa447ff30
Signed-off-by: Kun Jiang <kunx.jiang@intel.com>
Reviewed-on: http://android.intel.com:8080/46534
Reviewed-by: Zhang, Yanmin <yanmin.zhang@intel.com>
Reviewed-by: Yang, Fei <fei.yang@intel.com>
Tested-by: Ng, Cheon-woei <cheon-woei.ng@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
32 files changed:
drivers/infiniband/core/addr.c
drivers/infiniband/hw/cxgb3/iwch_cm.c
drivers/infiniband/hw/cxgb4/cm.c
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/nes/nes_cm.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/net/cxgb3/cxgb3_offload.c
drivers/s390/net/qeth_l3_main.c
drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
drivers/scsi/cxgbi/libcxgbi.c
include/net/arp.h
include/net/dst.h
net/atm/clip.c
net/bridge/br_netfilter.c
net/core/dst.c
net/core/neighbour.c
net/decnet/dn_neigh.c
net/decnet/dn_route.c
net/ipv4/arp.c
net/ipv4/ip_gre.c
net/ipv4/ip_output.c
net/ipv4/route.c
net/ipv6/addrconf.c
net/ipv6/ip6_fib.c
net/ipv6/ip6_output.c
net/ipv6/ndisc.c
net/ipv6/route.c
net/ipv6/sit.c
net/sched/sch_teql.c
net/xfrm/xfrm_policy.c