[PATCH] iommu/iova: Clear the slab cache pointers when destroying them

Davidlohr Bueso <[email protected]>
Newsgroups dev.linux.lists.iommu,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Both iova_cache_get() failure path and iova_cache_put() destroy the two
slab caches without clearing the pointers, leaving them dangling with
iova_cache_users at zero. The next iova_cache_get() then re-enters the
respective block, and if it fails early enough to reach 'out_err' before
re-creating both caches, it calls kmem_cache_destroy() a second time on
whichever cache is still stale:

  BUG: KASAN: slab-use-after-free in iova_cache_get+0x216/0x280
  Read of size 1 at addr ffff888001b9fdc0 by task swapper/0/1
  CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Not tainted 7.2.0-rc1 #2
  Call Trace:
   <TASK>
   dump_stack_lvl+0x53/0x70
   print_report+0xce/0x620
   kasan_report+0xce/0x100
   __kasan_check_byte+0x36/0x50
   kmem_cache_destroy+0x1b/0x1c0
   iova_cache_get+0x216/0x280
   ...
  Freed by task 1:
   kasan_save_stack+0x33/0x60
   kasan_save_track+0x14/0x30
   kasan_save_free_info+0x3b/0x60
   __kasan_slab_free+0x43/0x70
   kmem_cache_free+0xbe/0x3c0
   kobject_put+0x14d/0x280
   iova_cache_put+0x8e/0xd0

Clear both pointers after destroying them, in both places.

Fixes: 84e6f56be9c6 ("iommu/iova: use named kmem_cache for iova magazines")
Signed-off-by: Davidlohr Bueso <[email protected]>
---
 drivers/iommu/iova.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c
index b710e5ad37e2..0e8ea04b824f 100644
--- a/drivers/iommu/iova.c
+++ b/drivers/iommu/iova.c
@@ -984,6 +984,8 @@ int iova_cache_get(void)
 out_err:
 	kmem_cache_destroy(iova_cache);
 	kmem_cache_destroy(iova_magazine_cache);
+	iova_cache = NULL;
+	iova_magazine_cache = NULL;
 	mutex_unlock(&iova_cache_mutex);
 	return err;
 }
@@ -1001,6 +1003,8 @@ void iova_cache_put(void)
 		cpuhp_remove_multi_state(CPUHP_IOMMU_IOVA_DEAD);
 		kmem_cache_destroy(iova_cache);
 		kmem_cache_destroy(iova_magazine_cache);
+		iova_cache = NULL;
+		iova_magazine_cache = NULL;
 	}
 	mutex_unlock(&iova_cache_mutex);
 }
-- 
2.39.5
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.