au1000_close() calls free_irq() while aup->lock is still held with spin_lock_irqsave(). free_irq() can sleep because it takes the IRQ descriptor request mutex, so it does not belong inside the close-time spinlocked section. This issue was found by our static analysis tool and then manually reviewed against the current tree. The grounded PoC kept the ndo_stop carrier and the au1000_close() -> free_irq(dev->irq, dev) path while the driver lock was held. Lockdep reported: BUG: sleeping function called from invalid context 1 lock held by exploit/192: #0: (&aup->lock){....}-{2:2}, at: au1000_close+0x23/0x83 [vuln_msv] [ BUG: Invalid wait context ] exploit/192 is trying to lock: (&desc->request_mutex){+.+.}-{3:3}, at: free_irq+0x63/0x360 free_irq+0x63/0x360 au1000_close+0x65/0x83 [vuln_msv] Drop aup->lock before freeing the IRQ. The protected close-time work still stops the device and queue before IRQ teardown, but the sleepable IRQ core path now runs outside the spinlocked section. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Runyu Xiao --- drivers/net/ethernet/amd/au1000_eth.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c index 9d35ac348ebe..5a04056e38fa 100644 --- a/drivers/net/ethernet/amd/au1000_eth.c +++ b/drivers/net/ethernet/amd/au1000_eth.c @@ -943,9 +943,10 @@ static int au1000_close(struct net_device *dev) /* stop the device */ netif_stop_queue(dev); + spin_unlock_irqrestore(&aup->lock, flags); + /* disable the interrupt */ free_irq(dev->irq, dev); - spin_unlock_irqrestore(&aup->lock, flags); return 0; } -- 2.34.1