diff options
author | Deren Wu <deren.wu@mediatek.com> | 2024-01-13 12:00:22 +0300 |
---|---|---|
committer | Sasha Levin <sashal@kernel.org> | 2024-03-27 01:19:33 +0300 |
commit | c7dd42fbebcfb02bef070fd48f774d6412d0b49d (patch) | |
tree | 661746f8f83241bdd536bc90eff7a3737cc9064f /drivers/net/wireless/mediatek/mt76 | |
parent | cb8ae15877b09734def090b431212bff8f0a2e6a (diff) | |
download | linux-c7dd42fbebcfb02bef070fd48f774d6412d0b49d.tar.xz |
wifi: mt76: mt7921e: fix use-after-free in free_irq()
[ Upstream commit c957280ef6ab6bdf559a91ae693a6b34310697e3 ]
From commit a304e1b82808 ("[PATCH] Debug shared irqs"), there is a test
to make sure the shared irq handler should be able to handle the unexpected
event after deregistration. For this case, let's apply MT76_REMOVED flag to
indicate the device was removed and do not run into the resource access
anymore.
BUG: KASAN: use-after-free in mt7921_irq_handler+0xd8/0x100 [mt7921e]
Read of size 8 at addr ffff88824a7d3b78 by task rmmod/11115
CPU: 28 PID: 11115 Comm: rmmod Tainted: G W L 5.17.0 #10
Hardware name: Micro-Star International Co., Ltd. MS-7D73/MPG B650I
EDGE WIFI (MS-7D73), BIOS 1.81 01/05/2024
Call Trace:
<TASK>
dump_stack_lvl+0x6f/0xa0
print_address_description.constprop.0+0x1f/0x190
? mt7921_irq_handler+0xd8/0x100 [mt7921e]
? mt7921_irq_handler+0xd8/0x100 [mt7921e]
kasan_report.cold+0x7f/0x11b
? mt7921_irq_handler+0xd8/0x100 [mt7921e]
mt7921_irq_handler+0xd8/0x100 [mt7921e]
free_irq+0x627/0xaa0
devm_free_irq+0x94/0xd0
? devm_request_any_context_irq+0x160/0x160
? kobject_put+0x18d/0x4a0
mt7921_pci_remove+0x153/0x190 [mt7921e]
pci_device_remove+0xa2/0x1d0
__device_release_driver+0x346/0x6e0
driver_detach+0x1ef/0x2c0
bus_remove_driver+0xe7/0x2d0
? __check_object_size+0x57/0x310
pci_unregister_driver+0x26/0x250
__do_sys_delete_module+0x307/0x510
? free_module+0x6a0/0x6a0
? fpregs_assert_state_consistent+0x4b/0xb0
? rcu_read_lock_sched_held+0x10/0x70
? syscall_enter_from_user_mode+0x20/0x70
? trace_hardirqs_on+0x1c/0x130
do_syscall_64+0x5c/0x80
? trace_hardirqs_on_prepare+0x72/0x160
? do_syscall_64+0x68/0x80
? trace_hardirqs_on_prepare+0x72/0x160
entry_SYSCALL_64_after_hwframe+0x44/0xae
Reported-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Closes: https://lore.kernel.org/linux-wireless/CABXGCsOdvVwdLmSsC8TZ1jF0UOg_F_W3wqLECWX620PUkvNk=A@mail.gmail.com/
Fixes: 9270270d6219 ("wifi: mt76: mt7921: fix PCI DMA hang after reboot")
Tested-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Signed-off-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76')
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt7921/pci.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt792x_dma.c | 2 |
2 files changed, 3 insertions, 0 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c index f04e7095e181..49d4f3c4829e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c @@ -387,6 +387,7 @@ static void mt7921_pci_remove(struct pci_dev *pdev) struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); mt7921e_unregister_device(dev); + set_bit(MT76_REMOVED, &mdev->phy.state); devm_free_irq(&pdev->dev, pdev->irq, dev); mt76_free_device(&dev->mt76); pci_free_irq_vectors(pdev); diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c index a3dbd3865b2f..be3119aa9afa 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x_dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt792x_dma.c @@ -12,6 +12,8 @@ irqreturn_t mt792x_irq_handler(int irq, void *dev_instance) { struct mt792x_dev *dev = dev_instance; + if (test_bit(MT76_REMOVED, &dev->mt76.phy.state)) + return IRQ_NONE; mt76_wr(dev, dev->irq_map->host_irq_enable, 0); if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state)) |