Skip to content

Commit

Permalink
nfc: st-nci: Fix use after free bug in ndlc_remove due to race condition
Browse files Browse the repository at this point in the history
This bug influences both st_nci_i2c_remove and st_nci_spi_remove.
Take st_nci_i2c_remove as an example.

In st_nci_i2c_probe, it called ndlc_probe and bound &ndlc->sm_work
with llt_ndlc_sm_work.

When it calls ndlc_recv or timeout handler, it will finally call
schedule_work to start the work.

When we call st_nci_i2c_remove to remove the driver, there
may be a sequence as follows:

Fix it by finishing the work before cleanup in ndlc_remove

CPU0                  CPU1

                    |llt_ndlc_sm_work
st_nci_i2c_remove   |
  ndlc_remove       |
     st_nci_remove  |
     nci_free_device|
     kfree(ndev)    |
//free ndlc->ndev   |
                    |llt_ndlc_rcv_queue
                    |nci_recv_frame
                    |//use ndlc->ndev

Fixes: 35630df ("NFC: st21nfcb: Add driver for STMicroelectronics ST21NFCB NFC chip")
Signed-off-by: Zheng Wang <[email protected]>
Reviewed-by: Krzysztof Kozlowski <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
bluesheep1337 authored and kuba-moo committed Mar 15, 2023
1 parent cf18d55 commit 5000fe6
Showing 1 changed file with 4 additions and 2 deletions.
6 changes: 4 additions & 2 deletions drivers/nfc/st-nci/ndlc.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,13 +282,15 @@ EXPORT_SYMBOL(ndlc_probe);

void ndlc_remove(struct llt_ndlc *ndlc)
{
st_nci_remove(ndlc->ndev);

/* cancel timers */
del_timer_sync(&ndlc->t1_timer);
del_timer_sync(&ndlc->t2_timer);
ndlc->t2_active = false;
ndlc->t1_active = false;
/* cancel work */
cancel_work_sync(&ndlc->sm_work);

st_nci_remove(ndlc->ndev);

skb_queue_purge(&ndlc->rcv_q);
skb_queue_purge(&ndlc->send_q);
Expand Down

0 comments on commit 5000fe6

Please sign in to comment.