In the Linux kernel, the following vulnerability has been resolved:
iommu: Fix potential use-after-free during probe
Kasan has reported the following use after free on dev->iommu. when a device probe fails and it is in process of freeing dev->iommu in deviommufree function, a deferredprobeworkfunc runs in parallel and tries to access dev->iommu->fwspec in ofiommu_configure path thus causing use after free.
BUG: KASAN: use-after-free in ofiommuconfigure+0xb4/0x4a4 Read of size 8 at addr ffffff87a2f1acb8 by task kworker/u16:2/153
Workqueue: eventsunbound deferredprobeworkfunc Call trace: dumpbacktrace+0x0/0x33c showstack+0x18/0x24 dumpstacklvl+0x16c/0x1e0 printaddressdescription+0x84/0x39c _kasanreport+0x184/0x308 kasanreport+0x50/0x78 _asanload8+0xc0/0xc4 ofiommuconfigure+0xb4/0x4a4 ofdmaconfigureid+0x2fc/0x4d4 platformdmaconfigure+0x40/0x5c reallyprobe+0x1b4/0xb74 driverprobedevice+0x11c/0x228 _deviceattachdriver+0x14c/0x304 busforeachdrv+0x124/0x1b0 _deviceattach+0x25c/0x334 deviceinitialprobe+0x24/0x34 busprobedevice+0x78/0x134 deferredprobeworkfunc+0x130/0x1a8 processonework+0x4c8/0x970 workerthread+0x5c8/0xaec kthread+0x1f8/0x220 retfrom_fork+0x10/0x18
Allocated by task 1: _kasankmalloc+0xd4/0x114 _kasankmalloc+0x10/0x1c kmemcachealloctrace+0xe4/0x3d4 _iommuprobedevice+0x90/0x394 probeiommugroup+0x70/0x9c busforeachdev+0x11c/0x19c busiommuprobe+0xb8/0x7d4 bussetiommu+0xcc/0x13c armsmmubusinit+0x44/0x130 [armsmmu] armsmmudeviceprobe+0xb88/0xc54 [armsmmu] platformdrvprobe+0xe4/0x13c reallyprobe+0x2c8/0xb74 driverprobedevice+0x11c/0x228 devicedriverattach+0xf0/0x16c _driverattach+0x80/0x320 busforeachdev+0x11c/0x19c driverattach+0x38/0x48 busadddriver+0x1dc/0x3a4 driverregister+0x18c/0x244 _platformdriverregister+0x88/0x9c initmodule+0x64/0xff4 [armsmmu] dooneinitcall+0x17c/0x2f0 doinitmodule+0xe8/0x378 loadmodule+0x3f80/0x4a40 _sesysfinitmodule+0x1a0/0x1e4 _arm64sysfinitmodule+0x44/0x58 el0svccommon+0x100/0x264 doel0svc+0x38/0xa4 el0svc+0x20/0x30 el0synchandler+0x68/0xac el0_sync+0x160/0x180
Freed by task 1: kasansettrack+0x4c/0x84 kasansetfreeinfo+0x28/0x4c __kasanslabfree+0x120/0x15c _kasanslabfree+0x18/0x28 slabfreefreelisthook+0x204/0x2fc kfree+0xfc/0x3a4 _iommuprobedevice+0x284/0x394 probeiommugroup+0x70/0x9c busforeachdev+0x11c/0x19c busiommuprobe+0xb8/0x7d4 bussetiommu+0xcc/0x13c armsmmubusinit+0x44/0x130 [armsmmu] armsmmudeviceprobe+0xb88/0xc54 [armsmmu] platformdrvprobe+0xe4/0x13c reallyprobe+0x2c8/0xb74 driverprobedevice+0x11c/0x228 devicedriverattach+0xf0/0x16c _driverattach+0x80/0x320 busforeachdev+0x11c/0x19c driverattach+0x38/0x48 busadddriver+0x1dc/0x3a4 driverregister+0x18c/0x244 _platformdriverregister+0x88/0x9c initmodule+0x64/0xff4 [armsmmu] dooneinitcall+0x17c/0x2f0 doinitmodule+0xe8/0x378 loadmodule+0x3f80/0x4a40 _sesysfinitmodule+0x1a0/0x1e4 _arm64sysfinitmodule+0x44/0x58 el0svccommon+0x100/0x264 doel0svc+0x38/0xa4 el0svc+0x20/0x30 el0synchandler+0x68/0xac el0_sync+0x160/0x180
Fix this by setting dev->iommu to NULL first and then freeing deviommu structure in deviommu_free function.