[PATCH] iommufd: fix slab-use-after-free read in iommufd_ioas_unmap

From: l1za0 . sec

Date: Tue Apr 21 2026 - 09:52:19 EST


From: Haocheng Yu <l1za0.sec@xxxxxxxxx>

A KASAN: slab-use-after-free read in iommufd_ioas_unmap is reported
by a modified Syzkaller-based kernel fuzzing tool we developed.

This issue is caused by a race condition between iommufd_destroy()
and iommufd_put_object(). Thread A first enters iommufd_put_object(),
which is called by iommufd_ioas_umap(), and executes
`refcount_dec(&obj->users);`, but before executing
`up_read(&obj->destroy_rwsem);`, thread B happens to enter
iommufd_destroy() and destroy the object. Later, when A wants to
release the lock, it accesses this already destroyed object,
causing a use-after-free error.

To fix this issue, before executing the destroy statement in
iommufd_destroy(), a write lock is acquired using down_write() to
ensure that up_read() has finished executing before destroy,
thus avoiding the UAF problem.

Signed-off-by: Haocheng Yu <l1za0.sec@xxxxxxxxx>
---
drivers/iommu/iommufd/main.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c
index e71523cbd0de..a1f0b591c412 100644
--- a/drivers/iommu/iommufd/main.c
+++ b/drivers/iommu/iommufd/main.c
@@ -212,6 +212,8 @@ static int iommufd_destroy(struct iommufd_ucmd *ucmd)
obj = iommufd_object_remove(ucmd->ictx, cmd->id, false);
if (IS_ERR(obj))
return PTR_ERR(obj);
+ down_write(&obj->destroy_rwsem);
+ up_write(&obj->destroy_rwsem);
iommufd_object_ops[obj->type].destroy(obj);
kfree(obj);
return 0;

base-commit: ffc253263a1375a65fa6c9f62a893e9767fbebfa
--
2.51.0