Patch "net: alx: fix race condition in alx_remove" has been added to the 4.9-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net: alx: fix race condition in alx_remove

to the 4.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-alx-fix-race-condition-in-alx_remove.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 377c412032d44b2b8c4d1f5eb943c0d0ac008f08
Author: Zekun Shen <bruceshenzk@xxxxxxxxx>
Date:   Mon Jun 15 11:50:29 2020 -0400

    net: alx: fix race condition in alx_remove
    
    [ Upstream commit e89df5c4322c1bf495f62d74745895b5fd2a4393 ]
    
    There is a race condition exist during termination. The path is
    alx_stop and then alx_remove. An alx_schedule_link_check could be called
    before alx_stop by interrupt handler and invoke alx_link_check later.
    Alx_stop frees the napis, and alx_remove cancels any pending works.
    If any of the work is scheduled before termination and invoked before
    alx_remove, a null-ptr-deref occurs because both expect alx->napis[i].
    
    This patch fix the race condition by moving cancel_work_sync functions
    before alx_free_napis inside alx_stop. Because interrupt handler can call
    alx_schedule_link_check again, alx_free_irq is moved before
    cancel_work_sync calls too.
    
    Signed-off-by: Zekun Shen <bruceshenzk@xxxxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
index c0f84b73574d8..2a5bb1012385e 100644
--- a/drivers/net/ethernet/atheros/alx/main.c
+++ b/drivers/net/ethernet/atheros/alx/main.c
@@ -1056,8 +1056,12 @@ static int __alx_open(struct alx_priv *alx, bool resume)
 
 static void __alx_stop(struct alx_priv *alx)
 {
-	alx_halt(alx);
 	alx_free_irq(alx);
+
+	cancel_work_sync(&alx->link_check_wk);
+	cancel_work_sync(&alx->reset_wk);
+
+	alx_halt(alx);
 	alx_free_rings(alx);
 }
 
@@ -1659,9 +1663,6 @@ static void alx_remove(struct pci_dev *pdev)
 	struct alx_priv *alx = pci_get_drvdata(pdev);
 	struct alx_hw *hw = &alx->hw;
 
-	cancel_work_sync(&alx->link_check_wk);
-	cancel_work_sync(&alx->reset_wk);
-
 	/* restore permanent mac address */
 	alx_set_macaddr(hw, hw->perm_addr);
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux