The dirty bitmap ioctl paths derive a shift with __ffs() from the userspace supplied bitmap page size before comparing it with the IOMMU page size. A zero page size has undefined behavior, and a non-power-of-2 value makes the bitmap size check use a different granularity than the page size later accepted by the ioctl. Reject invalid bitmap page sizes before using them in shift arithmetic. Signed-off-by: Yousef Alhouseen --- drivers/vfio/vfio_iommu_type1.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index c8151ba54..9499381d0 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -2949,6 +2950,9 @@ static int vfio_iommu_type1_unmap_dma(struct vfio_iommu *iommu, if (!access_ok((void __user *)bitmap.data, bitmap.size)) return -EINVAL; + if (!is_power_of_2(bitmap.pgsize)) + return -EINVAL; + pgshift = __ffs(bitmap.pgsize); ret = verify_bitmap_size(unmap.size >> pgshift, bitmap.size); @@ -3039,6 +3043,9 @@ static int vfio_iommu_type1_dirty_pages(struct vfio_iommu *iommu, range.bitmap.size)) return -EINVAL; + if (!is_power_of_2(range.bitmap.pgsize)) + return -EINVAL; + pgshift = __ffs(range.bitmap.pgsize); ret = verify_bitmap_size(size >> pgshift, range.bitmap.size); -- 2.54.0