Skip to content

Commit e586e22

Browse files
jgunthorpejoergroedel
authored andcommitted
iommu: Protect against overflow in iommu_pgsize()
On a 32 bit system calling: iommu_map(0, 0x40000000) When using the AMD V1 page table type with a domain->pgsize of 0xfffff000 causes iommu_pgsize() to miscalculate a result of: size=0x40000000 count=2 count should be 1. This completely corrupts the mapping process. This is because the final test to adjust the pagesize malfunctions when the addition overflows. Use check_add_overflow() to prevent this. Fixes: b1d99dc ("iommu: Hook up '->unmap_pages' driver callback") Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> Link: https://lore.kernel.org/r/0-v1-3ad28fc2e3a3+163327-iommu_overflow_pgsize_jgg@nvidia.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent da33e87 commit e586e22

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

drivers/iommu/iommu.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2413,6 +2413,7 @@ static size_t iommu_pgsize(struct iommu_domain *domain, unsigned long iova,
24132413
unsigned int pgsize_idx, pgsize_idx_next;
24142414
unsigned long pgsizes;
24152415
size_t offset, pgsize, pgsize_next;
2416+
size_t offset_end;
24162417
unsigned long addr_merge = paddr | iova;
24172418

24182419
/* Page sizes supported by the hardware and small enough for @size */
@@ -2453,7 +2454,8 @@ static size_t iommu_pgsize(struct iommu_domain *domain, unsigned long iova,
24532454
* If size is big enough to accommodate the larger page, reduce
24542455
* the number of smaller pages.
24552456
*/
2456-
if (offset + pgsize_next <= size)
2457+
if (!check_add_overflow(offset, pgsize_next, &offset_end) &&
2458+
offset_end <= size)
24572459
size = offset;
24582460

24592461
out_set_count:

0 commit comments

Comments
 (0)