l2cap_sock_kill can be called in l2cap_sock_release and l2cap_sock_close_cb either. This lead l2cap_chan_destroy to be called twice for same channel. To prevent double list_del and double chan_put, chan_destroy should be protected with chan->refcnt and chan_list_lock so that reentrance could be forbidden. Signed-off-by: Minho Ban <mhban@xxxxxxxxxxx> --- net/bluetooth/l2cap_core.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 24f144b..156ca14 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -400,10 +400,14 @@ struct l2cap_chan *l2cap_chan_create(void) void l2cap_chan_destroy(struct l2cap_chan *chan) { write_lock(&chan_list_lock); + /* Check if channel is valid */ + if (!atomic_read(&chan->refcnt)) { + write_unlock(&chan_list_lock); + return; + } list_del(&chan->global_l); - write_unlock(&chan_list_lock); - l2cap_chan_put(chan); + write_unlock(&chan_list_lock); } void l2cap_chan_set_defaults(struct l2cap_chan *chan) -- 1.7.5.4 -- To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html