* [PATCH v1] iommu/vsi: Fix use-after-free during module unload
@ 2026-09-05 18:38 Yibo Tan
2026-09-07 7:30 ` Benjamin Gaignard
0 siblings, 1 reply; 5+ messages in thread
From: Yibo Tan @ 2026-09-05 18:38 UTC (permalink / raw)
To: Benjamin Gaignard, Joerg Roedel (AMD), Will Deacon
Cc: Robin Murphy, iommu, linux-kernel
iommu_device_register() links the embedded iommu_device into the IOMMU
core's global device list. The VSI driver can be built as a module, but
has no remove callback to unregister the device before devres frees the
containing struct vsi_iommu.
With no attached consumer holding a module reference, unloading
vsi-iommu.ko succeeds. A later platform device registration enters the
IOMMU bus notifier and scans the stale list entry. KASAN reports a
slab-use-after-free in __iommu_probe_device().
The missing unregister operation on driver unbind was also noted during
review of the driver's fwnode lookup lifetime handling.
Add the missing remove callback. Unregister the IOMMU device and remove
its sysfs object while the provider is still alive. Release the exact
shared IRQ action before forcing runtime suspend, then unprepare the
clocks acquired during probe.
The failure was reproduced on the 2026-08-11 IOMMU next snapshot with
real module load and unload syscalls. With the same KASAN kernel, the
unmodified driver produced two invalid reads from the same freed list
entry. The patched driver removed the entry, completed the later device
registration and produced no KASAN, WARNING, Oops or panic.
The remove callback also builds with W=1 for arm64 with
ARCH_ROCKCHIP=y and CONFIG_PM=y, and for the arm64 COMPILE_TEST path
with CONFIG_PM=n.
A standalone reproducer, the vulnerable and fixed serial logs, and
their checksums are available at:
https://github.com/kimaiden1984-boop/linux-vsi-iommu-unload-uaf-reproducer
Fixes: 917ace84b770 ("iommu: Add verisilicon IOMMU driver")
Link: https://lore.kernel.org/0e405cb3-1227-4ad2-96ff-aa0db3124381@arm.com/
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5
Signed-off-by: Yibo Tan <lhfff@tju.edu.cn>
---
The QEMU helper supplies the platform device, MMIO resource, IRQ and
firmware node normally provided by RK3588 hardware. The failing access
occurs while the IOMMU core scans its provider list, before VSI register
access.
Not tested on physical RK3588 hardware: removal with an attached
decoder, a runtime-active device, or concurrent interrupt delivery.
drivers/iommu/vsi-iommu.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/iommu/vsi-iommu.c b/drivers/iommu/vsi-iommu.c
index 42c424496..7fa7ee8cf 100644
--- a/drivers/iommu/vsi-iommu.c
+++ b/drivers/iommu/vsi-iommu.c
@@ -728,6 +728,17 @@ static int vsi_iommu_probe(struct platform_device *pdev)
return err;
}
+static void vsi_iommu_remove(struct platform_device *pdev)
+{
+ struct vsi_iommu *iommu = platform_get_drvdata(pdev);
+
+ iommu_device_unregister(&iommu->iommu);
+ iommu_device_sysfs_remove(&iommu->iommu);
+ devm_free_irq(&pdev->dev, iommu->irq, iommu);
+ pm_runtime_force_suspend(&pdev->dev);
+ clk_bulk_unprepare(iommu->num_clocks, iommu->clocks);
+}
+
static void vsi_iommu_shutdown(struct platform_device *pdev)
{
struct vsi_iommu *iommu = platform_get_drvdata(pdev);
@@ -776,6 +787,7 @@ static DEFINE_RUNTIME_DEV_PM_OPS(vsi_iommu_pm_ops,
static struct platform_driver rockchip_vsi_iommu_driver = {
.probe = vsi_iommu_probe,
+ .remove = vsi_iommu_remove,
.shutdown = vsi_iommu_shutdown,
.driver = {
.name = "vsi_iommu",
--
2.39.5
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1] iommu/vsi: Fix use-after-free during module unload
2026-09-05 18:38 [PATCH v1] iommu/vsi: Fix use-after-free during module unload Yibo Tan
@ 2026-09-07 7:30 ` Benjamin Gaignard
2026-09-07 19:22 ` Yibo Tan
2026-09-07 19:52 ` [PATCH v2] " Yibo Tan
0 siblings, 2 replies; 5+ messages in thread
From: Benjamin Gaignard @ 2026-09-07 7:30 UTC (permalink / raw)
To: Yibo Tan, Joerg Roedel (AMD), Will Deacon
Cc: Robin Murphy, iommu, linux-kernel
Le 05/09/2026 à 20:38, Yibo Tan a écrit :
> iommu_device_register() links the embedded iommu_device into the IOMMU
> core's global device list. The VSI driver can be built as a module, but
> has no remove callback to unregister the device before devres frees the
> containing struct vsi_iommu.
>
> With no attached consumer holding a module reference, unloading
> vsi-iommu.ko succeeds. A later platform device registration enters the
> IOMMU bus notifier and scans the stale list entry. KASAN reports a
> slab-use-after-free in __iommu_probe_device().
>
> The missing unregister operation on driver unbind was also noted during
> review of the driver's fwnode lookup lifetime handling.
>
> Add the missing remove callback. Unregister the IOMMU device and remove
> its sysfs object while the provider is still alive. Release the exact
> shared IRQ action before forcing runtime suspend, then unprepare the
> clocks acquired during probe.
>
> The failure was reproduced on the 2026-08-11 IOMMU next snapshot with
> real module load and unload syscalls. With the same KASAN kernel, the
> unmodified driver produced two invalid reads from the same freed list
> entry. The patched driver removed the entry, completed the later device
> registration and produced no KASAN, WARNING, Oops or panic.
>
> The remove callback also builds with W=1 for arm64 with
> ARCH_ROCKCHIP=y and CONFIG_PM=y, and for the arm64 COMPILE_TEST path
> with CONFIG_PM=n.
>
> A standalone reproducer, the vulnerable and fixed serial logs, and
> their checksums are available at:
>
> https://github.com/kimaiden1984-boop/linux-vsi-iommu-unload-uaf-reproducer
>
> Fixes: 917ace84b770 ("iommu: Add verisilicon IOMMU driver")
> Link: https://lore.kernel.org/0e405cb3-1227-4ad2-96ff-aa0db3124381@arm.com/
> Cc: stable@vger.kernel.org
> Assisted-by: Codex:GPT-5
> Signed-off-by: Yibo Tan <lhfff@tju.edu.cn>
> ---
> The QEMU helper supplies the platform device, MMIO resource, IRQ and
> firmware node normally provided by RK3588 hardware. The failing access
> occurs while the IOMMU core scans its provider list, before VSI register
> access.
>
> Not tested on physical RK3588 hardware: removal with an attached
> decoder, a runtime-active device, or concurrent interrupt delivery.
>
> drivers/iommu/vsi-iommu.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/drivers/iommu/vsi-iommu.c b/drivers/iommu/vsi-iommu.c
> index 42c424496..7fa7ee8cf 100644
> --- a/drivers/iommu/vsi-iommu.c
> +++ b/drivers/iommu/vsi-iommu.c
> @@ -728,6 +728,17 @@ static int vsi_iommu_probe(struct platform_device *pdev)
> return err;
> }
>
> +static void vsi_iommu_remove(struct platform_device *pdev)
> +{
> + struct vsi_iommu *iommu = platform_get_drvdata(pdev);
> +
> + iommu_device_unregister(&iommu->iommu);
> + iommu_device_sysfs_remove(&iommu->iommu);
> + devm_free_irq(&pdev->dev, iommu->irq, iommu);
I don't think devm_free_irq() is needed here.
That said we need to fix the problem.
Why not introduce devm_ functions for iommu_device_unregister(), iommu_device_sysfs_remove() and
clk_bulk_unprepare() ? That could be useful for lot of drivers.
Regards,
Benjamin
> + pm_runtime_force_suspend(&pdev->dev);
> + clk_bulk_unprepare(iommu->num_clocks, iommu->clocks);
> +}
> +
> static void vsi_iommu_shutdown(struct platform_device *pdev)
> {
> struct vsi_iommu *iommu = platform_get_drvdata(pdev);
> @@ -776,6 +787,7 @@ static DEFINE_RUNTIME_DEV_PM_OPS(vsi_iommu_pm_ops,
>
> static struct platform_driver rockchip_vsi_iommu_driver = {
> .probe = vsi_iommu_probe,
> + .remove = vsi_iommu_remove,
> .shutdown = vsi_iommu_shutdown,
> .driver = {
> .name = "vsi_iommu",
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v1] iommu/vsi: Fix use-after-free during module unload
2026-09-07 7:30 ` Benjamin Gaignard
@ 2026-09-07 19:22 ` Yibo Tan
2026-09-07 19:52 ` [PATCH v2] " Yibo Tan
1 sibling, 0 replies; 5+ messages in thread
From: Yibo Tan @ 2026-09-07 19:22 UTC (permalink / raw)
To: Benjamin Gaignard
Cc: Joerg Roedel, Will Deacon, Robin Murphy, iommu, linux-kernel
Thanks for the review.
I agree that devm_free_irq() is unnecessary and have removed it. The
same KASAN A/B test still passes: the unmodified driver reports two
use-after-free accesses, while the revised driver removes the IOMMU
registration and completes the later device registration without KASAN
or other diagnostics.
For v2, I propose keeping the bug fix local so it remains small,
independently testable and suitable for stable backporting. The remove
callback revokes the non-managed IOMMU and sysfs registrations and
balances the clock preparation, while leaving the managed IRQ to
devres.
Reusable managed helpers for the IOMMU registrations and clock
preparation could then be developed and reviewed as a separate series,
without making this UAF fix depend on a cross-subsystem API change.
Regards,
Yibo
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2] iommu/vsi: Fix use-after-free during module unload
2026-09-07 7:30 ` Benjamin Gaignard
2026-09-07 19:22 ` Yibo Tan
@ 2026-09-07 19:52 ` Yibo Tan
2026-09-08 10:40 ` Benjamin Gaignard
1 sibling, 1 reply; 5+ messages in thread
From: Yibo Tan @ 2026-09-07 19:52 UTC (permalink / raw)
To: Benjamin Gaignard, Joerg Roedel (AMD), Will Deacon
Cc: Robin Murphy, iommu, linux-kernel
iommu_device_register() links the embedded iommu_device into the IOMMU
core's global device list. The VSI driver can be built as a module, but
has no remove callback to unregister the device before devres frees the
containing struct vsi_iommu.
With no attached consumer holding a module reference, unloading
vsi-iommu.ko succeeds. A later platform device registration enters the
IOMMU bus notifier and scans the stale list entry. KASAN reports a
slab-use-after-free in __iommu_probe_device().
The missing unregister operation on driver unbind was also noted during
review of the driver's fwnode lookup lifetime handling.
Add the missing remove callback. Unregister the IOMMU device and remove
its sysfs object while the provider is still alive, then force runtime
suspend and unprepare the clocks acquired during probe. Leave the IRQ
and other managed resources to devres teardown.
The failure was reproduced with real module load and unload syscalls.
With the same KASAN kernel, the unmodified driver produced two invalid
reads from the same freed list entry. The patched driver removed the
entry, completed the later device registration and produced no KASAN,
WARNING, Oops or panic.
The remove callback also builds with W=1 for arm64 with
ARCH_ROCKCHIP=y and CONFIG_PM=y, and for the arm64 COMPILE_TEST path
with CONFIG_PM=n.
A standalone reproducer, the vulnerable and fixed serial logs, and
their checksums are available at:
https://github.com/kimaiden1984-boop/linux-vsi-iommu-unload-uaf-reproducer
Fixes: 917ace84b770 ("iommu: Add verisilicon IOMMU driver")
Link: https://lore.kernel.org/0e405cb3-1227-4ad2-96ff-aa0db3124381@arm.com/
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5
Signed-off-by: Yibo Tan <lhfff@tju.edu.cn>
---
Changes in v2:
- Drop devm_free_irq() and leave managed IRQ teardown to devres.
- Re-run the KASAN A/B test and arm64 PM-enabled and PM-disabled builds.
v1: https://lore.kernel.org/all/20260905183834.3447662-1-lhfff@tju.edu.cn/
drivers/iommu/vsi-iommu.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/iommu/vsi-iommu.c b/drivers/iommu/vsi-iommu.c
index 42c424496d07..f73bcc82c472 100644
--- a/drivers/iommu/vsi-iommu.c
+++ b/drivers/iommu/vsi-iommu.c
@@ -728,6 +728,16 @@ static int vsi_iommu_probe(struct platform_device *pdev)
return err;
}
+static void vsi_iommu_remove(struct platform_device *pdev)
+{
+ struct vsi_iommu *iommu = platform_get_drvdata(pdev);
+
+ iommu_device_unregister(&iommu->iommu);
+ iommu_device_sysfs_remove(&iommu->iommu);
+ pm_runtime_force_suspend(&pdev->dev);
+ clk_bulk_unprepare(iommu->num_clocks, iommu->clocks);
+}
+
static void vsi_iommu_shutdown(struct platform_device *pdev)
{
struct vsi_iommu *iommu = platform_get_drvdata(pdev);
@@ -776,6 +786,7 @@ static DEFINE_RUNTIME_DEV_PM_OPS(vsi_iommu_pm_ops,
static struct platform_driver rockchip_vsi_iommu_driver = {
.probe = vsi_iommu_probe,
+ .remove = vsi_iommu_remove,
.shutdown = vsi_iommu_shutdown,
.driver = {
.name = "vsi_iommu",
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2] iommu/vsi: Fix use-after-free during module unload
2026-09-07 19:52 ` [PATCH v2] " Yibo Tan
@ 2026-09-08 10:40 ` Benjamin Gaignard
0 siblings, 0 replies; 5+ messages in thread
From: Benjamin Gaignard @ 2026-09-08 10:40 UTC (permalink / raw)
To: Yibo Tan, Joerg Roedel (AMD), Will Deacon
Cc: Robin Murphy, iommu, linux-kernel
Le 07/09/2026 à 21:52, Yibo Tan a écrit :
> iommu_device_register() links the embedded iommu_device into the IOMMU
> core's global device list. The VSI driver can be built as a module, but
> has no remove callback to unregister the device before devres frees the
> containing struct vsi_iommu.
>
> With no attached consumer holding a module reference, unloading
> vsi-iommu.ko succeeds. A later platform device registration enters the
> IOMMU bus notifier and scans the stale list entry. KASAN reports a
> slab-use-after-free in __iommu_probe_device().
>
> The missing unregister operation on driver unbind was also noted during
> review of the driver's fwnode lookup lifetime handling.
>
> Add the missing remove callback. Unregister the IOMMU device and remove
> its sysfs object while the provider is still alive, then force runtime
> suspend and unprepare the clocks acquired during probe. Leave the IRQ
> and other managed resources to devres teardown.
>
> The failure was reproduced with real module load and unload syscalls.
> With the same KASAN kernel, the unmodified driver produced two invalid
> reads from the same freed list entry. The patched driver removed the
> entry, completed the later device registration and produced no KASAN,
> WARNING, Oops or panic.
>
> The remove callback also builds with W=1 for arm64 with
> ARCH_ROCKCHIP=y and CONFIG_PM=y, and for the arm64 COMPILE_TEST path
> with CONFIG_PM=n.
>
> A standalone reproducer, the vulnerable and fixed serial logs, and
> their checksums are available at:
>
> https://github.com/kimaiden1984-boop/linux-vsi-iommu-unload-uaf-reproducer
>
> Fixes: 917ace84b770 ("iommu: Add verisilicon IOMMU driver")
> Link: https://lore.kernel.org/0e405cb3-1227-4ad2-96ff-aa0db3124381@arm.com/
> Cc: stable@vger.kernel.org
> Assisted-by: Codex:GPT-5
> Signed-off-by: Yibo Tan <lhfff@tju.edu.cn>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
> ---
> Changes in v2:
> - Drop devm_free_irq() and leave managed IRQ teardown to devres.
> - Re-run the KASAN A/B test and arm64 PM-enabled and PM-disabled builds.
>
> v1: https://lore.kernel.org/all/20260905183834.3447662-1-lhfff@tju.edu.cn/
>
> drivers/iommu/vsi-iommu.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/drivers/iommu/vsi-iommu.c b/drivers/iommu/vsi-iommu.c
> index 42c424496d07..f73bcc82c472 100644
> --- a/drivers/iommu/vsi-iommu.c
> +++ b/drivers/iommu/vsi-iommu.c
> @@ -728,6 +728,16 @@ static int vsi_iommu_probe(struct platform_device *pdev)
> return err;
> }
>
> +static void vsi_iommu_remove(struct platform_device *pdev)
> +{
> + struct vsi_iommu *iommu = platform_get_drvdata(pdev);
> +
> + iommu_device_unregister(&iommu->iommu);
> + iommu_device_sysfs_remove(&iommu->iommu);
> + pm_runtime_force_suspend(&pdev->dev);
> + clk_bulk_unprepare(iommu->num_clocks, iommu->clocks);
> +}
> +
> static void vsi_iommu_shutdown(struct platform_device *pdev)
> {
> struct vsi_iommu *iommu = platform_get_drvdata(pdev);
> @@ -776,6 +786,7 @@ static DEFINE_RUNTIME_DEV_PM_OPS(vsi_iommu_pm_ops,
>
> static struct platform_driver rockchip_vsi_iommu_driver = {
> .probe = vsi_iommu_probe,
> + .remove = vsi_iommu_remove,
> .shutdown = vsi_iommu_shutdown,
> .driver = {
> .name = "vsi_iommu",
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-08 10:40 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-05 18:38 [PATCH v1] iommu/vsi: Fix use-after-free during module unload Yibo Tan
2026-09-07 7:30 ` Benjamin Gaignard
2026-09-07 19:22 ` Yibo Tan
2026-09-07 19:52 ` [PATCH v2] " Yibo Tan
2026-09-08 10:40 ` Benjamin Gaignard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®