Skip to content

Commit 7655739

Browse files
rmurphy-armwildea01
authored andcommitted
iommu/io-pgtable: Sanitise map/unmap addresses
It may be an egregious error to attempt to use addresses outside the range of the pagetable format, but that still doesn't mean we should merrily wreak havoc by silently mapping/unmapping whatever truncated portions of them might happen to correspond to real addresses. Add some up-front checks to sanitise our inputs so that buggy callers don't invite potential memory corruption. Signed-off-by: Robin Murphy <[email protected]> Signed-off-by: Will Deacon <[email protected]>
1 parent c54451a commit 7655739

File tree

2 files changed

+13
-0
lines changed

2 files changed

+13
-0
lines changed

drivers/iommu/io-pgtable-arm-v7s.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,9 @@ static int arm_v7s_map(struct io_pgtable_ops *ops, unsigned long iova,
479479
if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
480480
return 0;
481481

482+
if (WARN_ON(upper_32_bits(iova) || upper_32_bits(paddr)))
483+
return -ERANGE;
484+
482485
ret = __arm_v7s_map(data, iova, paddr, size, prot, 1, data->pgd);
483486
/*
484487
* Synchronise all PTE updates for the new mapping before there's
@@ -659,6 +662,9 @@ static int arm_v7s_unmap(struct io_pgtable_ops *ops, unsigned long iova,
659662
struct arm_v7s_io_pgtable *data = io_pgtable_ops_to_data(ops);
660663
size_t unmapped;
661664

665+
if (WARN_ON(upper_32_bits(iova)))
666+
return 0;
667+
662668
unmapped = __arm_v7s_unmap(data, iova, size, 1, data->pgd);
663669
if (unmapped)
664670
io_pgtable_tlb_sync(&data->iop);

drivers/iommu/io-pgtable-arm.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,10 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
452452
if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
453453
return 0;
454454

455+
if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias) ||
456+
paddr >= (1ULL << data->iop.cfg.oas)))
457+
return -ERANGE;
458+
455459
prot = arm_lpae_prot_to_pte(data, iommu_prot);
456460
ret = __arm_lpae_map(data, iova, paddr, size, prot, lvl, ptep);
457461
/*
@@ -610,6 +614,9 @@ static int arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova,
610614
arm_lpae_iopte *ptep = data->pgd;
611615
int lvl = ARM_LPAE_START_LVL(data);
612616

617+
if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias)))
618+
return 0;
619+
613620
unmapped = __arm_lpae_unmap(data, iova, size, lvl, ptep);
614621
if (unmapped)
615622
io_pgtable_tlb_sync(&data->iop);

0 commit comments

Comments
 (0)