linux-uconsole/net/tipc
Jon Paul Maloy 59e0cd110f tipc: fix socket timer deadlock
commit f1d048f24e upstream.

We sometimes observe a 'deadly embrace' type deadlock occurring
between mutually connected sockets on the same node. This happens
when the one-hour peer supervision timers happen to expire
simultaneously in both sockets.

The scenario is as follows:

CPU 1:                          CPU 2:
--------                        --------
tipc_sk_timeout(sk1)            tipc_sk_timeout(sk2)
  lock(sk1.slock)                 lock(sk2.slock)
  msg_create(probe)               msg_create(probe)
  unlock(sk1.slock)               unlock(sk2.slock)
  tipc_node_xmit_skb()            tipc_node_xmit_skb()
    tipc_node_xmit()                tipc_node_xmit()
      tipc_sk_rcv(sk2)                tipc_sk_rcv(sk1)
        lock(sk2.slock)                 lock((sk1.slock)
        filter_rcv()                    filter_rcv()
          tipc_sk_proto_rcv()             tipc_sk_proto_rcv()
            msg_create(probe_rsp)           msg_create(probe_rsp)
            tipc_sk_respond()               tipc_sk_respond()
              tipc_node_xmit_skb()            tipc_node_xmit_skb()
                tipc_node_xmit()                tipc_node_xmit()
                  tipc_sk_rcv(sk1)                tipc_sk_rcv(sk2)
                    lock((sk1.slock)                lock((sk2.slock)
                    ===> DEADLOCK                   ===> DEADLOCK

Further analysis reveals that there are three different locations in the
socket code where tipc_sk_respond() is called within the context of the
socket lock, with ensuing risk of similar deadlocks.

We now solve this by passing a buffer queue along with all upcalls where
sk_lock.slock may potentially be held. Response or rejected message
buffers are accumulated into this queue instead of being sent out
directly, and only sent once we know we are safely outside the slock
context.

Reported-by: GUNA <gbalasun@gmail.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-04-30 05:49:28 +02:00
..
addr.c tipc: simplify include dependencies 2015-05-14 12:24:45 -04:00
addr.h tipc: simplify include dependencies 2015-05-14 12:24:45 -04:00
bcast.c tipc: unlock in error path 2016-03-03 15:07:07 -08:00
bcast.h tipc: clean up unused code and structures 2015-10-24 06:56:47 -07:00
bearer.c tipc: clean up unused code and structures 2015-10-24 06:56:47 -07:00
bearer.h tipc: clean up unused code and structures 2015-10-24 06:56:47 -07:00
core.c tipc: make dist queue pernet 2017-04-30 05:49:27 +02:00
core.h tipc: make dist queue pernet 2017-04-30 05:49:27 +02:00
discover.c tipc: let neighbor discoverer tranmsit consumable buffers 2015-10-24 06:56:44 -07:00
discover.h tipc: involve namespace infrastructure 2015-01-12 16:24:32 -05:00
eth_media.c tipc: make media address offset a common define 2015-02-27 18:18:48 -05:00
ib_media.c tipc: rename media/msg related definitions 2015-02-27 18:18:48 -05:00
Kconfig tipc: add ip/udp media type 2015-03-05 22:08:42 -05:00
link.c tipc: move linearization of buffers to generic code 2016-09-24 10:07:35 +02:00
link.h tipc: clean up unused code and structures 2015-10-24 06:56:47 -07:00
Makefile tipc: add ip/udp media type 2015-03-05 22:08:42 -05:00
msg.c tipc: let broadcast packet reception use new link receive function 2015-10-24 06:56:37 -07:00
msg.h tipc: let broadcast packet reception use new link receive function 2015-10-24 06:56:37 -07:00
name_distr.c tipc: fix random link resets while adding a second bearer 2017-04-30 05:49:28 +02:00
name_distr.h tipc: resolve race problem at unicast message reception 2015-02-05 16:00:02 -08:00
name_table.c tipc: rename functions defined in subscr.c 2015-05-04 15:04:00 -04:00
name_table.h tipc: convert legacy nl name table dump to nl compat 2015-02-09 13:20:48 -08:00
net.c tipc: create broadcast transmission link at namespace init 2015-10-24 06:56:27 -07:00
net.h tipc: make tipc node table aware of net namespace 2015-01-12 16:24:32 -05:00
netlink.c tipc: move and rename the legacy nl api to "nl compat" 2015-02-09 13:20:47 -08:00
netlink.h tipc: move and rename the legacy nl api to "nl compat" 2015-02-09 13:20:47 -08:00
netlink_compat.c tipc: fix nl compat regression for link statistics 2016-09-15 08:27:49 +02:00
node.c tipc: correct error in node fsm 2017-04-30 05:49:27 +02:00
node.h tipc: clean up unused code and structures 2015-10-24 06:56:47 -07:00
server.c tipc: use sock_create_kern interface to create kernel socket 2015-05-14 13:39:33 -04:00
server.h tipc: make subscriber server support net namespace 2015-01-12 16:24:33 -05:00
socket.c tipc: fix socket timer deadlock 2017-04-30 05:49:28 +02:00
socket.h tipc: clean up socket layer message reception 2015-07-26 16:31:50 -07:00
subscr.c tipc: fix nullptr crash during subscription cancel 2016-09-15 08:27:44 +02:00
subscr.h tipc: rename functions defined in subscr.c 2015-05-04 15:04:00 -04:00
sysctl.c tipc: add name distributor resiliency queue 2014-09-01 17:51:48 -07:00
udp_media.c tipc: make sure IPv6 header fits in skb headroom 2017-04-30 05:49:27 +02:00