From: Kunkun Jiang jiangkunkun@huawei.com
virt inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8UZSP CVE: NA
------------------------------
Some parameters in iommu_clear_dirty_log/vfio_iova_dirty_log_clear have uncorrect type, which used in bitmap operations. In some cases, it will cause data overflow.
Fixes: bbf3b39e5576b (iommu: Introduce dirty log tracking framework) Fixes: f1c9b9fa4fbc0 (vfio/iommu_type1: Add support for manual dirty log clear) Signed-off-by: Kunkun Jiang jiangkunkun@huawei.com Reviewed-by: Keqian Zhu zhukeqian1@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: jiaqingtong jiaqingtong@huawei.com --- drivers/iommu/iommu.c | 7 +++---- drivers/vfio/vfio_iommu_type1.c | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 4cd140bb3175..40912af6c304 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -2910,9 +2910,8 @@ int iommu_clear_dirty_log(struct iommu_domain *domain, unsigned long bitmap_pgshift) { unsigned long riova, rsize; - unsigned int min_pagesz; + unsigned int min_pagesz, rs, re; bool flush = false; - int rs, re, start, end; int ret = 0;
min_pagesz = 1 << __ffs(domain->pgsize_bitmap); @@ -2932,8 +2931,8 @@ int iommu_clear_dirty_log(struct iommu_domain *domain, end = start + (size >> bitmap_pgshift); bitmap_for_each_set_region(bitmap, rs, re, start, end) { flush = true; - riova = base_iova + (rs << bitmap_pgshift); - rsize = (re - rs) << bitmap_pgshift; + riova = base_iova + ((unsigned long)rs << bitmap_pgshift); + rsize = (unsigned long)(re - rs) << bitmap_pgshift; ret = __iommu_clear_dirty_log(domain, riova, rsize, bitmap, base_iova, bitmap_pgshift); if (ret) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 88081c22e1c3..b7c9f4f3b796 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -1210,7 +1210,7 @@ static int vfio_iova_dirty_log_clear(u64 __user *bitmap, unsigned long bitmap_size; unsigned long *bitmap_buffer = NULL; bool clear_valid; - int rs, re, start, end, dma_offset; + unsigned int rs, re, dma_offset; int ret = 0;
bitmap_size = DIRTY_BITMAP_BYTES(size >> pgshift); @@ -1242,7 +1242,7 @@ static int vfio_iova_dirty_log_clear(u64 __user *bitmap, end = (end_iova - iova) >> pgshift; bitmap_for_each_set_region(bitmap_buffer, rs, re, start, end) { clear_valid = true; - riova = iova + (rs << pgshift); + riova = iova + ((unsigned long)rs << pgshift); dma_offset = (riova - dma->iova) >> pgshift; bitmap_clear(dma->bitmap, dma_offset, re - rs); }