Chester Lin 6ec02e
From 5000fe6c27827a61d8250a7e4a1d26c3298ef4f6 Mon Sep 17 00:00:00 2001
Chester Lin 6ec02e
From: Zheng Wang <zyytlz.wz@163.com>
Chester Lin 6ec02e
Date: Mon, 13 Mar 2023 00:08:37 +0800
Chester Lin 6ec02e
Subject: [PATCH] nfc: st-nci: Fix use after free bug in ndlc_remove due to race condition
Chester Lin 6ec02e
Git-commit: 5000fe6c27827a61d8250a7e4a1d26c3298ef4f6
Chester Lin 6ec02e
Patch-mainline: v6.3-rc3
Chester Lin 6ec02e
References: git-fixes bsc#1210337 CVE-2023-1990
Chester Lin 6ec02e
Chester Lin 6ec02e
This bug influences both st_nci_i2c_remove and st_nci_spi_remove.
Chester Lin 6ec02e
Take st_nci_i2c_remove as an example.
Chester Lin 6ec02e
Chester Lin 6ec02e
In st_nci_i2c_probe, it called ndlc_probe and bound &ndlc->sm_work
Chester Lin 6ec02e
with llt_ndlc_sm_work.
Chester Lin 6ec02e
Chester Lin 6ec02e
When it calls ndlc_recv or timeout handler, it will finally call
Chester Lin 6ec02e
schedule_work to start the work.
Chester Lin 6ec02e
Chester Lin 6ec02e
When we call st_nci_i2c_remove to remove the driver, there
Chester Lin 6ec02e
may be a sequence as follows:
Chester Lin 6ec02e
Chester Lin 6ec02e
Fix it by finishing the work before cleanup in ndlc_remove
Chester Lin 6ec02e
Chester Lin 6ec02e
CPU0                  CPU1
Chester Lin 6ec02e
Chester Lin 6ec02e
                    |llt_ndlc_sm_work
Chester Lin 6ec02e
st_nci_i2c_remove   |
Chester Lin 6ec02e
  ndlc_remove       |
Chester Lin 6ec02e
     st_nci_remove  |
Chester Lin 6ec02e
     nci_free_device|
Chester Lin 6ec02e
     kfree(ndev)    |
Chester Lin 6ec02e
//free ndlc->ndev   |
Chester Lin 6ec02e
                    |llt_ndlc_rcv_queue
Chester Lin 6ec02e
                    |nci_recv_frame
Chester Lin 6ec02e
                    |//use ndlc->ndev
Chester Lin 6ec02e
Chester Lin 6ec02e
Fixes: 35630df68d60 ("NFC: st21nfcb: Add driver for STMicroelectronics ST21NFCB NFC chip")
Chester Lin 6ec02e
Signed-off-by: Zheng Wang <zyytlz.wz@163.com>
Chester Lin 6ec02e
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Chester Lin 6ec02e
Link: https://lore.kernel.org/r/20230312160837.2040857-1-zyytlz.wz@163.com
Chester Lin 6ec02e
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Chester Lin 6ec02e
Acked-by: Takashi Iwai <tiwai@suse.de>
Chester Lin 6ec02e
Acked-by: Chester Lin <clin@suse.com>
Chester Lin 6ec02e
---
Chester Lin 6ec02e
 drivers/nfc/st-nci/ndlc.c | 6 ++++--
Chester Lin 6ec02e
 1 file changed, 4 insertions(+), 2 deletions(-)
Chester Lin 6ec02e
Chester Lin 6ec02e
diff --git a/drivers/nfc/st-nci/ndlc.c b/drivers/nfc/st-nci/ndlc.c
Chester Lin 6ec02e
index 755460a73c0d..d2aa9f766738 100644
Chester Lin 6ec02e
--- a/drivers/nfc/st-nci/ndlc.c
Chester Lin 6ec02e
+++ b/drivers/nfc/st-nci/ndlc.c
Chester Lin 6ec02e
@@ -282,13 +282,15 @@ EXPORT_SYMBOL(ndlc_probe);
Chester Lin 6ec02e
 
Chester Lin 6ec02e
 void ndlc_remove(struct llt_ndlc *ndlc)
Chester Lin 6ec02e
 {
Chester Lin 6ec02e
-	st_nci_remove(ndlc->ndev);
Chester Lin 6ec02e
-
Chester Lin 6ec02e
 	/* cancel timers */
Chester Lin 6ec02e
 	del_timer_sync(&ndlc->t1_timer);
Chester Lin 6ec02e
 	del_timer_sync(&ndlc->t2_timer);
Chester Lin 6ec02e
 	ndlc->t2_active = false;
Chester Lin 6ec02e
 	ndlc->t1_active = false;
Chester Lin 6ec02e
+	/* cancel work */
Chester Lin 6ec02e
+	cancel_work_sync(&ndlc->sm_work);
Chester Lin 6ec02e
+
Chester Lin 6ec02e
+	st_nci_remove(ndlc->ndev);
Chester Lin 6ec02e
 
Chester Lin 6ec02e
 	skb_queue_purge(&ndlc->rcv_q);
Chester Lin 6ec02e
 	skb_queue_purge(&ndlc->send_q);
Chester Lin 6ec02e
-- 
Chester Lin 6ec02e
2.35.3
Chester Lin 6ec02e