Eric Dumazet 6bd4f355df ipv6: kill sk_dst_lock
While testing the np->opt RCU conversion, I found that UDP/IPv6 was
using a mixture of xchg() and sk_dst_lock to protect concurrent changes
to sk->sk_dst_cache, leading to possible corruptions and crashes.

ip6_sk_dst_lookup_flow() uses sk_dst_check() anyway, so the simplest
way to fix the mess is to remove sk_dst_lock completely, as we did for
IPv4.

__ip6_dst_store() and ip6_dst_store() share same implementation.

sk_setup_caps() being called with socket lock being held or not,
we have to use sk_dst_set() instead of __sk_dst_set()

Note that I had to move the "np->dst_cookie = rt6_get_cookie(rt);"
in ip6_dst_store() before the sk_setup_caps(sk, dst) call.

This is because ip6_dst_store() can be called from process context,
without any lock held.

As soon as the dst is installed in sk->sk_dst_cache, dst can be freed
from another cpu doing a concurrent ip6_dst_store()

Doing the dst dereference before doing the install is needed to make
sure no use after free would trigger.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2015-12-03 11:32:06 -05:00
..
2014-09-18 10:54:36 +02:00
2015-03-04 00:23:23 -05:00
2015-06-28 16:55:44 -07:00
2015-03-06 21:50:02 -05:00
2015-09-17 17:18:37 -07:00
2015-10-08 04:27:03 -07:00
2013-11-07 19:28:58 -05:00
2014-09-30 01:02:26 -04:00
2015-09-24 12:25:23 -07:00
2015-11-02 22:47:14 -05:00
2015-12-03 11:32:06 -05:00
2015-09-24 09:34:43 +09:00
2015-10-13 04:55:04 -07:00
2014-01-03 20:56:48 -05:00
2015-10-08 04:27:03 -07:00
2015-10-23 06:26:42 -07:00
2015-09-17 21:09:07 -07:00
2014-06-02 11:00:41 -07:00
2015-12-03 11:32:06 -05:00
2015-03-12 22:58:12 -04:00
2015-10-26 22:24:22 -07:00
2015-10-08 04:27:03 -07:00