summaryrefslogtreecommitdiffstats
path: root/drivers/iommu/iommufd
diff options
context:
space:
mode:
authorKoichiro Den <den@valinux.co.jp>2023-10-28 01:29:42 +0900
committerJason Gunthorpe <jgg@nvidia.com>2023-10-30 11:36:04 -0300
commite7250ab7ca4998fe026f2149805b03e09dc32498 (patch)
treedf3a20124624a34a43527321699f87f1d9ea31c2 /drivers/iommu/iommufd
parent03476e687eb07b94f7cdb07cd3c7c4304b6c58b3 (diff)
downloadlinux-e7250ab7ca4998fe026f2149805b03e09dc32498.tar.gz
linux-e7250ab7ca4998fe026f2149805b03e09dc32498.tar.bz2
linux-e7250ab7ca4998fe026f2149805b03e09dc32498.zip
iommufd: Fix missing update of domains_itree after splitting iopt_area
In iopt_area_split(), if the original iopt_area has filled a domain and is linked to domains_itree, pages_nodes have to be properly reinserted. Otherwise the domains_itree becomes corrupted and we will UAF. Fixes: 51fe6141f0f6 ("iommufd: Data structure to provide IOVA to PFN mapping") Link: https://lore.kernel.org/r/20231027162941.2864615-2-den@valinux.co.jp Cc: stable@vger.kernel.org Signed-off-by: Koichiro Den <den@valinux.co.jp> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Diffstat (limited to 'drivers/iommu/iommufd')
-rw-r--r--drivers/iommu/iommufd/io_pagetable.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/iommu/iommufd/io_pagetable.c b/drivers/iommu/iommufd/io_pagetable.c
index 9f060abe53b6..c3e7791f8201 100644
--- a/drivers/iommu/iommufd/io_pagetable.c
+++ b/drivers/iommu/iommufd/io_pagetable.c
@@ -1220,6 +1220,16 @@ static int iopt_area_split(struct iopt_area *area, unsigned long iova)
if (WARN_ON(rc))
goto err_remove_lhs;
+ /*
+ * If the original area has filled a domain, domains_itree has to be
+ * updated.
+ */
+ if (area->storage_domain) {
+ interval_tree_remove(&area->pages_node, &pages->domains_itree);
+ interval_tree_insert(&lhs->pages_node, &pages->domains_itree);
+ interval_tree_insert(&rhs->pages_node, &pages->domains_itree);
+ }
+
lhs->storage_domain = area->storage_domain;
lhs->pages = area->pages;
rhs->storage_domain = area->storage_domain;