linux/net/ipv4
Pavel Emelyanov 076931989f [INET]: Fix inet_diag register vs rcv race
The following race is possible when one cpu unregisters the handler
while other one is trying to receive a message and call this one:

CPU1:                                                 CPU2:
inet_diag_rcv()                                       inet_diag_unregister()
  mutex_lock(&inet_diag_mutex);
  netlink_rcv_skb(skb, &inet_diag_rcv_msg);
    if (inet_diag_table[nlh->nlmsg_type] == 
                               NULL) /* false handler is still registered */
    ...
    netlink_dump_start(idiagnl, skb, nlh,
                           inet_diag_dump, NULL);
           cb = kzalloc(sizeof(*cb), GFP_KERNEL);
                   /* sleep here freeing memory 
                    * or preempt
                    * or sleep later on nlk->cb_mutex
                    */
                                                         spin_lock(&inet_diag_register_lock);
                                                         inet_diag_table[type] = NULL;
    ...                                                  spin_unlock(&inet_diag_register_lock);
                                                         synchronize_rcu();
                                                         /* CPU1 is sleeping - RCU quiescent
                                                          * state is passed
                                                          */
                                                         return;
    /* inet_diag_dump is finally called: */
    inet_diag_dump()
      handler = inet_diag_table[cb->nlh->nlmsg_type];
      BUG_ON(handler == NULL); 
      /* OOPS! While we slept the unregister has set
       * handler to NULL :(
       */

Grep showed, that the register/unregister functions are called
from init/fini module callbacks for tcp_/dccp_diag, so it's OK
to use the inet_diag_mutex to synchronize manipulations with the
inet_diag_table and the access to it.

Besides, as Herbert pointed out, asynchronous dumps should hold 
this mutex as well, and thus, we provide the mutex as cb_mutex one.

Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2007-11-30 00:08:14 +11:00
..
ipvs [IPVS]: Fix compiler warning about unused register_ip_vs_protocol 2007-11-20 17:44:01 -08:00
netfilter [NETFILTER]: Fix kernel panic with REDIRECT target. 2007-11-20 04:27:35 -08:00
af_inet.c [NET]: Forget the zero_it argument of sk_alloc() 2007-11-01 00:39:31 -07:00
ah4.c cleanup asm/scatterlist.h includes 2007-11-02 08:47:06 +01:00
arp.c [IPV4]: Remove bogus ifdef mess in arp_process 2007-11-26 23:17:53 +08:00
cipso_ipv4.c [NetLabel]: correct usage of RCU locking 2007-10-26 04:29:08 -07:00
datagram.c [IPV4]: Fix "ipOutNoRoutes" counter error for TCP and UDP 2007-06-03 18:08:50 -07:00
devinet.c [IPV4]: When possible test for IFF_LOOPBACK and not dev == loopback_dev 2007-10-10 16:52:48 -07:00
esp4.c [NET]: Fix incorrect sg_mark_end() calls. 2007-10-30 21:29:29 -07:00
fib_frontend.c [IPV4]: Compact some ifdefs in the fib code. 2007-11-07 04:11:41 -08:00
fib_hash.c [NET]: Make core networking code use seq_open_private 2007-10-10 16:55:33 -07:00
fib_lookup.h [RTNETLINK]: Fix sending netlink message when replace route. 2007-05-24 16:36:53 -07:00
fib_rules.c [INET]: Small possible memory leak in FIB rules 2007-11-10 22:12:03 -08:00
fib_semantics.c [NETLINK]: Introduce nested and byteorder flag to netlink attribute 2007-10-10 16:49:16 -07:00
fib_trie.c remove asm/bitops.h includes 2007-10-19 11:53:41 -07:00
icmp.c [INET]: Unexport icmpmsg_statistics 2007-10-26 04:06:08 -07:00
igmp.c [NET]: Make core networking code use seq_open_private 2007-10-10 16:55:33 -07:00
inet_connection_sock.c [INET]: Justification for local port range robustness. 2007-10-18 22:00:17 -07:00
inet_diag.c [INET]: Fix inet_diag register vs rcv race 2007-11-30 00:08:14 +11:00
inet_fragment.c [INET]: Consolidate frag queues freeing 2007-10-17 19:48:26 -07:00
inet_hashtables.c [INET]: Remove per bucket rwlock in tcp/dccp ehash table. 2007-11-07 04:15:11 -08:00
inet_lro.c fix endianness bug in inet_lro 2007-10-14 12:41:52 -07:00
inet_timewait_sock.c [INET]: Remove per bucket rwlock in tcp/dccp ehash table. 2007-11-07 04:15:11 -08:00
inetpeer.c [INET]: Use list_head-s in inetpeer.c 2007-11-12 21:27:28 -08:00
ip_forward.c [IPV4]: Uninline netfilter okfns 2007-10-15 12:26:35 -07:00
ip_fragment.c [NET]: Fix uninitialised variable in ip_frag_reasm() 2007-10-17 21:37:22 -07:00
ip_gre.c [NET]: Treat the sign of the result of skb_headroom() consistently 2007-10-23 21:27:55 -07:00
ip_input.c [IPV4]: Uninline netfilter okfns 2007-10-15 12:26:35 -07:00
ip_options.c [IPV4] ip_options.c: kmalloc + memset conversion to kzalloc 2007-07-31 14:06:45 -07:00
ip_output.c [IPV4]: Consolidate the ip cork destruction in ip_output.c 2007-11-07 04:08:25 -08:00
ip_sockglue.c [IPV4]: Clean the ip_sockglue.c from some ugly ifdefs 2007-11-07 04:08:55 -08:00
ipcomp.c [IPSEC]: Fix crypto_alloc_comp error checking 2007-11-07 04:15:03 -08:00
ipconfig.c [NET]: Wrap netdevice hardware header creation. 2007-10-10 16:52:50 -07:00
ipip.c [NET]: Treat the sign of the result of skb_headroom() consistently 2007-10-23 21:27:55 -07:00
ipmr.c [NET]: Make core networking code use seq_open_private 2007-10-10 16:55:33 -07:00
Kconfig typo fixes 2007-10-20 01:34:40 +02:00
Makefile [INET]: Collect frag queues management objects together 2007-10-15 12:26:39 -07:00
netfilter.c [NETFILTER]: Replace sk_buff ** with sk_buff * 2007-10-15 12:26:29 -07:00
proc.c [NET]: Define infrastructure to keep 'inuse' changes in an efficent SMP/NUMA way. 2007-11-07 04:08:57 -08:00
protocol.c [IPV4]: align inet_protos[] on SMP 2007-04-25 22:28:20 -07:00
raw.c [IPV4]: Use the {DEFINE|REF}_PROTO_INUSE infrastructure 2007-11-07 04:08:58 -08:00
route.c [NET]: Corrects a bug in ip_rt_acct_read() 2007-11-18 18:47:38 -08:00
syncookies.c [SK_BUFF]: Introduce tcp_hdr(), remove skb->h.th 2007-04-25 22:25:26 -07:00
sysctl_net_ipv4.c [TCP]: Problem bug with sysctl_tcp_congestion_control function 2007-11-19 23:28:21 -08:00
tcp_bic.c [TCP]: Remove num_acked>0 checks from cong.ctrl mods pkts_acked 2007-10-10 16:47:55 -07:00
tcp_cong.c [TCP]: remove unused argument to cong_avoid op 2007-07-18 01:46:58 -07:00
tcp_cubic.c [TCP]: Remove num_acked>0 checks from cong.ctrl mods pkts_acked 2007-10-10 16:47:55 -07:00
tcp_diag.c [INET]: Let inet_diag and friends autoload 2007-10-22 02:59:54 -07:00
tcp_highspeed.c [TCP]: remove unused argument to cong_avoid op 2007-07-18 01:46:58 -07:00
tcp_htcp.c [TCP]: H-TCP maxRTT estimation at startup 2007-08-07 18:29:05 -07:00
tcp_hybla.c [TCP]: remove unused argument to cong_avoid op 2007-07-18 01:46:58 -07:00
tcp_illinois.c [TCP]: congestion control API pass RTT in microseconds 2007-07-31 02:27:57 -07:00
tcp_input.c [TCP] FRTO: Clear frto_highmark only after process_frto that uses it 2007-11-14 15:55:09 -08:00
tcp_ipv4.c [IPV4] TCPMD5: Use memmove() instead of memcpy() because we have overlaps. 2007-11-20 17:30:31 -08:00
tcp_lp.c [TCP]: congestion control API pass RTT in microseconds 2007-07-31 02:27:57 -07:00
tcp_minisocks.c [TCP]: Move sack_ok access to obviously named funcs & cleanup 2007-10-10 16:48:00 -07:00
tcp_output.c [TCP] MTUprobe: Cleanup send queue check (no need to loop) 2007-11-23 19:10:56 +08:00
tcp_probe.c [NET]: Make /proc/net per network namespace 2007-10-10 16:49:06 -07:00
tcp_scalable.c [TCP]: remove unused argument to cong_avoid op 2007-07-18 01:46:58 -07:00
tcp_timer.c [TCP]: Move sack_ok access to obviously named funcs & cleanup 2007-10-10 16:48:00 -07:00
tcp_vegas.c [TCP] vegas: Fix a bug in disabling slow start by gamma parameter. 2007-10-29 22:37:25 -07:00
tcp_vegas.h [TCP]: congestion control API pass RTT in microseconds 2007-07-31 02:27:57 -07:00
tcp_veno.c [TCP]: congestion control API pass RTT in microseconds 2007-07-31 02:27:57 -07:00
tcp_westwood.c [TCP]: congestion control API pass RTT in microseconds 2007-07-31 02:27:57 -07:00
tcp_yeah.c [TCP]: congestion control API pass RTT in microseconds 2007-07-31 02:27:57 -07:00
tcp.c [INET]: Remove per bucket rwlock in tcp/dccp ehash table. 2007-11-07 04:15:11 -08:00
tunnel4.c [INET]: Cleanup the xfrm4_tunnel_(un)register 2007-11-10 21:48:54 -08:00
udp_impl.h [UDP]: Randomize port selection. 2007-10-10 16:48:31 -07:00
udp.c [IPV4]: Use the {DEFINE|REF}_PROTO_INUSE infrastructure 2007-11-07 04:08:58 -08:00
udplite.c [IPV4]: Use the {DEFINE|REF}_PROTO_INUSE infrastructure 2007-11-07 04:08:58 -08:00
xfrm4_input.c [IPSEC]: Rename mode to outer_mode and add inner_mode 2007-10-17 21:35:51 -07:00
xfrm4_mode_beet.c [IPSEC]: Add missing BEET checks 2007-10-17 21:31:50 -07:00
xfrm4_mode_transport.c [IPSEC]: Use IPv6 calling convention as the convention for x->mode->output 2007-10-10 16:55:54 -07:00
xfrm4_mode_tunnel.c [IPSEC]: Add missing BEET checks 2007-10-17 21:31:50 -07:00
xfrm4_output.c [IPSEC]: Rename mode to outer_mode and add inner_mode 2007-10-17 21:35:51 -07:00
xfrm4_policy.c [IPSEC]: Rename mode to outer_mode and add inner_mode 2007-10-17 21:35:51 -07:00
xfrm4_state.c [IPSEC]: Store afinfo pointer in xfrm_mode 2007-10-17 21:33:12 -07:00
xfrm4_tunnel.c [IPSEC]: Move tunnel parsing for IPv4 out of xfrm4_input 2007-10-17 21:28:53 -07:00