Commit 3536da06 authored by Samuel Ortiz's avatar Samuel Ortiz
Browse files

NFC: llcp: Clean local timers and works when removing a device

Whenever an adapter is removed we must clean all the local structures,
especially the timers and scheduled work. Otherwise those asynchronous
threads will eventually try to access the freed nfc_dev pointer if an LLCP
link is up.
Signed-off-by: default avatarSamuel Ortiz <>
parent b141e811
...@@ -142,20 +142,25 @@ struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local) ...@@ -142,20 +142,25 @@ struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
return local; return local;
} }
static void local_release(struct kref *ref) static void local_cleanup(struct nfc_llcp_local *local, bool listen)
{ {
struct nfc_llcp_local *local; nfc_llcp_socket_release(local, listen);
local = container_of(ref, struct nfc_llcp_local, ref);
nfc_llcp_socket_release(local, false);
del_timer_sync(&local->link_timer); del_timer_sync(&local->link_timer);
skb_queue_purge(&local->tx_queue); skb_queue_purge(&local->tx_queue);
cancel_work_sync(&local->tx_work); cancel_work_sync(&local->tx_work);
cancel_work_sync(&local->rx_work); cancel_work_sync(&local->rx_work);
cancel_work_sync(&local->timeout_work); cancel_work_sync(&local->timeout_work);
kfree_skb(local->rx_pending); kfree_skb(local->rx_pending);
static void local_release(struct kref *ref)
struct nfc_llcp_local *local;
local = container_of(ref, struct nfc_llcp_local, ref);
local_cleanup(local, false);
kfree(local); kfree(local);
} }
...@@ -1427,6 +1432,8 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev) ...@@ -1427,6 +1432,8 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev)
return; return;
} }
local_cleanup(local, false);
nfc_llcp_local_put(local); nfc_llcp_local_put(local);
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment