linux/net/ipv6
Christoph Paasch e337e24d66 inet: Fix kmemleak in tcp_v4/6_syn_recv_sock and dccp_v4/6_request_recv_sock
If in either of the above functions inet_csk_route_child_sock() or
__inet_inherit_port() fails, the newsk will not be freed:

unreferenced object 0xffff88022e8a92c0 (size 1592):
  comm "softirq", pid 0, jiffies 4294946244 (age 726.160s)
  hex dump (first 32 bytes):
    0a 01 01 01 0a 01 01 02 00 00 00 00 a7 cc 16 00  ................
    02 00 03 01 00 00 00 00 00 00 00 00 00 00 00 00  ................
  backtrace:
    [<ffffffff8153d190>] kmemleak_alloc+0x21/0x3e
    [<ffffffff810ab3e7>] kmem_cache_alloc+0xb5/0xc5
    [<ffffffff8149b65b>] sk_prot_alloc.isra.53+0x2b/0xcd
    [<ffffffff8149b784>] sk_clone_lock+0x16/0x21e
    [<ffffffff814d711a>] inet_csk_clone_lock+0x10/0x7b
    [<ffffffff814ebbc3>] tcp_create_openreq_child+0x21/0x481
    [<ffffffff814e8fa5>] tcp_v4_syn_recv_sock+0x3a/0x23b
    [<ffffffff814ec5ba>] tcp_check_req+0x29f/0x416
    [<ffffffff814e8e10>] tcp_v4_do_rcv+0x161/0x2bc
    [<ffffffff814eb917>] tcp_v4_rcv+0x6c9/0x701
    [<ffffffff814cea9f>] ip_local_deliver_finish+0x70/0xc4
    [<ffffffff814cec20>] ip_local_deliver+0x4e/0x7f
    [<ffffffff814ce9f8>] ip_rcv_finish+0x1fc/0x233
    [<ffffffff814cee68>] ip_rcv+0x217/0x267
    [<ffffffff814a7bbe>] __netif_receive_skb+0x49e/0x553
    [<ffffffff814a7cc3>] netif_receive_skb+0x50/0x82

This happens, because sk_clone_lock initializes sk_refcnt to 2, and thus
a single sock_put() is not enough to free the memory. Additionally, things
like xfrm, memcg, cookie_values,... may have been initialized.
We have to free them properly.

This is fixed by forcing a call to tcp_done(), ending up in
inet_csk_destroy_sock, doing the final sock_put(). tcp_done() is necessary,
because it ends up doing all the cleanup on xfrm, memcg, cookie_values,
xfrm,...

Before calling tcp_done, we have to set the socket to SOCK_DEAD, to
force it entering inet_csk_destroy_sock. To avoid the warning in
inet_csk_destroy_sock, inet_num has to be set to 0.
As inet_csk_destroy_sock does a dec on orphan_count, we first have to
increase it.

Calling tcp_done() allows us to remove the calls to
tcp_clear_xmit_timer() and tcp_cleanup_congestion_control().

A similar approach is taken for dccp by calling dccp_done().

This is in the kernel since 093d282321 (tproxy: fix hash locking issue
when using port redirection in __inet_inherit_port()), thus since
version >= 2.6.37.

Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
Signed-off-by: David S. Miller <davem@davemloft.net>
2012-12-14 13:14:07 -05:00
..
netfilter netfilter: nf_nat: Handle routing changes in MASQUERADE target 2012-12-03 15:14:20 +01:00
addrconf_core.c net: cleanup unsigned to unsigned int 2012-04-15 12:44:40 -04:00
addrconf.c ipv6: Protect ->mc_forwarding access with CONFIG_IPV6_MROUTE 2012-12-04 14:46:34 -05:00
addrlabel.c net: Enable a userns root rtnl calls that are safe for unprivilged users 2012-11-18 20:33:36 -05:00
af_inet6.c net: Make CAP_NET_BIND_SERVICE per user namespace 2012-11-18 20:33:37 -05:00
ah6.c ipv6: use IS_ENABLED() 2012-11-01 12:41:35 -04:00
anycast.c ipv6: avoid taking locks at socket dismantle 2012-12-05 16:01:28 -05:00
datagram.c net: Allow userns root to control ipv6 2012-11-18 20:32:45 -05:00
esp6.c net: ipv6: fix error return code 2012-08-31 16:27:48 -04:00
exthdrs_core.c Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jesse/openvswitch 2012-11-30 12:01:30 -05:00
exthdrs_offload.c ipv6: Pull IPv6 GSO registration out of the module 2012-11-15 17:39:24 -05:00
exthdrs.c ipv6: Pull IPv6 GSO registration out of the module 2012-11-15 17:39:24 -05:00
fib6_rules.c ipv6: introduce ip6_rt_put() 2012-11-03 14:59:05 -04:00
icmp.c net: Enable some sysctls that are safe for the userns root 2012-11-18 20:33:00 -05:00
inet6_connection_sock.c ipv6: fix inet6_csk_update_pmtu() return value 2012-11-20 15:16:15 -05:00
inet6_hashtables.c net: move inet_dport/inet_num in sock_common 2012-11-30 15:02:56 -05:00
ip6_fib.c ipv6: add support of equal cost multipath (ECMP) 2012-10-23 02:38:32 -04:00
ip6_flowlabel.c net: Allow userns root to control ipv6 2012-11-18 20:32:45 -05:00
ip6_gre.c net: Allow userns root to control ipv6 2012-11-18 20:32:45 -05:00
ip6_input.c net: TCP early demux cleanup 2012-07-30 14:53:21 -07:00
ip6_offload.c net: Remove code duplication between offload structures 2012-11-15 17:39:51 -05:00
ip6_offload.h ipv6: Pull IPv6 GSO registration out of the module 2012-11-15 17:39:24 -05:00
ip6_output.c ipv6: Update ipv6 static library with newly needed functions 2012-11-15 17:39:23 -05:00
ip6_tunnel.c ip6tnl/sit: drop packet if ECN present with not-ECT 2012-11-28 11:37:11 -05:00
ip6mr.c ip6mr: fix rtm_family of rtnl msg 2012-12-04 13:27:24 -05:00
ipcomp6.c ipv6: Add redirect support to all protocol icmp error handlers. 2012-07-12 00:25:15 -07:00
ipv6_sockglue.c net: Allow userns root to control ipv6 2012-11-18 20:32:45 -05:00
Kconfig gre: Support GRE over IPv6 2012-08-14 14:28:32 -07:00
Makefile ipv6: Preserve ipv6 functionality needed by NET 2012-11-18 02:34:00 -05:00
mcast.c ipv6: avoid taking locks at socket dismantle 2012-12-05 16:01:28 -05:00
mip6.c ipv6: mip6: fix mip6_mh_filter() 2012-09-25 16:04:44 -04:00
ndisc.c ipv6: Change skb->data before using icmpv6_notify() to propagate redirect 2012-12-14 13:14:07 -05:00
netfilter.c netfilter: ipv6: expand skb head in ip6_route_me_harder after oif change 2012-08-30 03:00:15 +02:00
output_core.c ipv6: Update ipv6 static library with newly needed functions 2012-11-15 17:39:23 -05:00
proc.c net: ipv6: proc: Fix error handling 2012-08-14 14:45:07 -07:00
protocol.c ipv6: Pull IPv6 GSO registration out of the module 2012-11-15 17:39:24 -05:00
raw.c ipv6: use IS_ENABLED() 2012-11-01 12:41:35 -04:00
reassembly.c net: Don't export sysctls to unprivileged users 2012-11-18 20:30:55 -05:00
route.c ipv6: Fix default route failover when CONFIG_IPV6_ROUTER_PREF=n 2012-12-03 15:34:47 -05:00
sit.c ip6tnl/sit: drop packet if ECN present with not-ECT 2012-11-28 11:37:11 -05:00
syncookies.c tcp: better retrans tracking for defer-accept 2012-11-03 14:45:00 -04:00
sysctl_net_ipv6.c net: Enable some sysctls that are safe for the userns root 2012-11-18 20:33:00 -05:00
tcp_ipv6.c inet: Fix kmemleak in tcp_v4/6_syn_recv_sock and dccp_v4/6_request_recv_sock 2012-12-14 13:14:07 -05:00
tcpv6_offload.c net: Remove code duplication between offload structures 2012-11-15 17:39:51 -05:00
tunnel6.c net: ipv6: Standardize prefixes for message logging 2012-05-16 01:01:03 -04:00
udp_impl.h net: Make setsockopt() optlen be unsigned. 2009-09-30 16:12:20 -07:00
udp_offload.c ipv6: Fix build error with udp_offload 2012-11-15 22:48:32 -05:00
udp.c ipv6: Pull IPv6 GSO registration out of the module 2012-11-15 17:39:24 -05:00
udplite.c Merge branch 'modsplit-Oct31_2011' of git://git.kernel.org/pub/scm/linux/kernel/git/paulg/linux 2011-11-06 19:44:47 -08:00
xfrm6_input.c netfilter: ipv6: use NFPROTO values for NF_HOOK invocation 2010-03-25 16:00:49 +01:00
xfrm6_mode_beet.c ipsec: be careful of non existing mac headers 2012-02-23 16:50:45 -05:00
xfrm6_mode_ro.c
xfrm6_mode_transport.c
xfrm6_mode_tunnel.c ipsec: be careful of non existing mac headers 2012-02-23 16:50:45 -05:00
xfrm6_output.c xfrm6: remove unneeded NULL check in __xfrm6_output() 2012-02-01 02:52:48 -05:00
xfrm6_policy.c xfrm6: Remove commented out function call to xfrm6_input_fini 2012-11-16 08:07:56 +01:00
xfrm6_state.c ipv6: use IS_ENABLED() 2012-11-01 12:41:35 -04:00
xfrm6_tunnel.c net: cleanup unsigned to unsigned int 2012-04-15 12:44:40 -04:00