twx-linux/net/tipc
Erik Hugne a5d0e7c037 tipc: fix spinlock recursion bug for failed subscriptions
If a topology event subscription fails for any reason, such as out
of memory, max number reached or because we received an invalid
request the correct behavior is to terminate the subscribers
connection to the topology server. This is currently broken and
produces the following oops:

[27.953662] tipc: Subscription rejected, illegal request
[27.955329] BUG: spinlock recursion on CPU#1, kworker/u4:0/6
[27.957066]  lock: 0xffff88003c67f408, .magic: dead4ead, .owner: kworker/u4:0/6, .owner_cpu: 1
[27.958054] CPU: 1 PID: 6 Comm: kworker/u4:0 Not tainted 3.14.0-rc6+ #5
[27.960230] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[27.960874] Workqueue: tipc_rcv tipc_recv_work [tipc]
[27.961430]  ffff88003c67f408 ffff88003de27c18 ffffffff815c0207 ffff88003de1c050
[27.962292]  ffff88003de27c38 ffffffff815beec5 ffff88003c67f408 ffffffff817f0a8a
[27.963152]  ffff88003de27c58 ffffffff815beeeb ffff88003c67f408 ffffffffa0013520
[27.964023] Call Trace:
[27.964292]  [<ffffffff815c0207>] dump_stack+0x45/0x56
[27.964874]  [<ffffffff815beec5>] spin_dump+0x8c/0x91
[27.965420]  [<ffffffff815beeeb>] spin_bug+0x21/0x26
[27.965995]  [<ffffffff81083df6>] do_raw_spin_lock+0x116/0x140
[27.966631]  [<ffffffff815c6215>] _raw_spin_lock_bh+0x15/0x20
[27.967256]  [<ffffffffa0008540>] subscr_conn_shutdown_event+0x20/0xa0 [tipc]
[27.968051]  [<ffffffffa000fde4>] tipc_close_conn+0xa4/0xb0 [tipc]
[27.968722]  [<ffffffffa00101ba>] tipc_conn_terminate+0x1a/0x30 [tipc]
[27.969436]  [<ffffffffa00089a2>] subscr_conn_msg_event+0x1f2/0x2f0 [tipc]
[27.970209]  [<ffffffffa0010000>] tipc_receive_from_sock+0x90/0xf0 [tipc]
[27.970972]  [<ffffffffa000fa79>] tipc_recv_work+0x29/0x50 [tipc]
[27.971633]  [<ffffffff8105dbf5>] process_one_work+0x165/0x3e0
[27.972267]  [<ffffffff8105e869>] worker_thread+0x119/0x3a0
[27.972896]  [<ffffffff8105e750>] ? manage_workers.isra.25+0x2a0/0x2a0
[27.973622]  [<ffffffff810648af>] kthread+0xdf/0x100
[27.974168]  [<ffffffff810647d0>] ? kthread_create_on_node+0x1a0/0x1a0
[27.974893]  [<ffffffff815ce13c>] ret_from_fork+0x7c/0xb0
[27.975466]  [<ffffffff810647d0>] ? kthread_create_on_node+0x1a0/0x1a0

The recursion occurs when subscr_terminate tries to grab the
subscriber lock, which is already taken by subscr_conn_msg_event.
We fix this by checking if the request to establish a new
subscription was successful, and if not we initiate termination of
the subscriber after we have released the subscriber lock.

Signed-off-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-03-24 15:36:56 -04:00
..
addr.c
addr.h
bcast.c
bcast.h
bearer.c tipc: make bearer set up in module insertion stage 2014-02-22 00:00:15 -05:00
bearer.h
config.c tipc: allow connection shutdown callback to be invoked in advance 2014-03-06 14:46:23 -05:00
config.h
core.c tipc: make bearer set up in module insertion stage 2014-02-22 00:00:15 -05:00
core.h tipc: make bearer set up in module insertion stage 2014-02-22 00:00:15 -05:00
discover.c
discover.h
eth_media.c
handler.c tipc: don't log disabled tasklet handler errors 2014-03-06 14:46:24 -05:00
ib_media.c
Kconfig
link.c tipc: fix message corruption bug for deferred packets 2014-02-13 16:35:05 -05:00
link.h
log.c
Makefile
msg.c
msg.h
name_distr.c
name_distr.h
name_table.c tipc: fix memory leak during module removal 2014-03-06 14:46:24 -05:00
name_table.h
net.c
net.h
netlink.c tipc: remove all enabled flags from all tipc components 2014-02-22 00:00:15 -05:00
node_subscr.c
node_subscr.h
node.c
node.h
port.c
port.h
ref.c tipc: remove all enabled flags from all tipc components 2014-02-22 00:00:15 -05:00
ref.h
server.c tipc: fix connection refcount leak 2014-03-06 14:46:23 -05:00
server.h tipc: remove all enabled flags from all tipc components 2014-02-22 00:00:15 -05:00
socket.c tipc: avoid to unnecessary process switch under non-block mode 2014-03-06 14:46:23 -05:00
subscr.c tipc: fix spinlock recursion bug for failed subscriptions 2014-03-24 15:36:56 -04:00
subscr.h
sysctl.c