@@ -1613,6 +1613,37 @@ static void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev,
1613
1613
trace_amdgpu_vm_bo_map (bo_va , mapping );
1614
1614
}
1615
1615
1616
+ /* Validate operation parameters to prevent potential abuse */
1617
+ static int amdgpu_vm_verify_parameters (struct amdgpu_device * adev ,
1618
+ struct amdgpu_bo * bo ,
1619
+ uint64_t saddr ,
1620
+ uint64_t offset ,
1621
+ uint64_t size )
1622
+ {
1623
+ uint64_t tmp , lpfn ;
1624
+
1625
+ if (saddr & AMDGPU_GPU_PAGE_MASK
1626
+ || offset & AMDGPU_GPU_PAGE_MASK
1627
+ || size & AMDGPU_GPU_PAGE_MASK )
1628
+ return - EINVAL ;
1629
+
1630
+ if (check_add_overflow (saddr , size , & tmp )
1631
+ || check_add_overflow (offset , size , & tmp )
1632
+ || size == 0 /* which also leads to end < begin */ )
1633
+ return - EINVAL ;
1634
+
1635
+ /* make sure object fit at this offset */
1636
+ if (bo && offset + size > amdgpu_bo_size (bo ))
1637
+ return - EINVAL ;
1638
+
1639
+ /* Ensure last pfn not exceed max_pfn */
1640
+ lpfn = (saddr + size - 1 ) >> AMDGPU_GPU_PAGE_SHIFT ;
1641
+ if (lpfn >= adev -> vm_manager .max_pfn )
1642
+ return - EINVAL ;
1643
+
1644
+ return 0 ;
1645
+ }
1646
+
1616
1647
/**
1617
1648
* amdgpu_vm_bo_map - map bo inside a vm
1618
1649
*
@@ -1639,21 +1670,14 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
1639
1670
struct amdgpu_bo * bo = bo_va -> base .bo ;
1640
1671
struct amdgpu_vm * vm = bo_va -> base .vm ;
1641
1672
uint64_t eaddr ;
1673
+ int r ;
1642
1674
1643
- /* validate the parameters */
1644
- if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK )
1645
- return - EINVAL ;
1646
- if (saddr + size <= saddr || offset + size <= offset )
1647
- return - EINVAL ;
1648
-
1649
- /* make sure object fit at this offset */
1650
- eaddr = saddr + size - 1 ;
1651
- if ((bo && offset + size > amdgpu_bo_size (bo )) ||
1652
- (eaddr >= adev -> vm_manager .max_pfn << AMDGPU_GPU_PAGE_SHIFT ))
1653
- return - EINVAL ;
1675
+ r = amdgpu_vm_verify_parameters (adev , bo , saddr , offset , size );
1676
+ if (r )
1677
+ return r ;
1654
1678
1655
1679
saddr /= AMDGPU_GPU_PAGE_SIZE ;
1656
- eaddr /= AMDGPU_GPU_PAGE_SIZE ;
1680
+ eaddr = saddr + ( size - 1 ) / AMDGPU_GPU_PAGE_SIZE ;
1657
1681
1658
1682
tmp = amdgpu_vm_it_iter_first (& vm -> va , saddr , eaddr );
1659
1683
if (tmp ) {
@@ -1706,17 +1730,9 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
1706
1730
uint64_t eaddr ;
1707
1731
int r ;
1708
1732
1709
- /* validate the parameters */
1710
- if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK )
1711
- return - EINVAL ;
1712
- if (saddr + size <= saddr || offset + size <= offset )
1713
- return - EINVAL ;
1714
-
1715
- /* make sure object fit at this offset */
1716
- eaddr = saddr + size - 1 ;
1717
- if ((bo && offset + size > amdgpu_bo_size (bo )) ||
1718
- (eaddr >= adev -> vm_manager .max_pfn << AMDGPU_GPU_PAGE_SHIFT ))
1719
- return - EINVAL ;
1733
+ r = amdgpu_vm_verify_parameters (adev , bo , saddr , offset , size );
1734
+ if (r )
1735
+ return r ;
1720
1736
1721
1737
/* Allocate all the needed memory */
1722
1738
mapping = kmalloc (sizeof (* mapping ), GFP_KERNEL );
@@ -1730,7 +1746,7 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
1730
1746
}
1731
1747
1732
1748
saddr /= AMDGPU_GPU_PAGE_SIZE ;
1733
- eaddr /= AMDGPU_GPU_PAGE_SIZE ;
1749
+ eaddr = saddr + ( size - 1 ) / AMDGPU_GPU_PAGE_SIZE ;
1734
1750
1735
1751
mapping -> start = saddr ;
1736
1752
mapping -> last = eaddr ;
@@ -1817,10 +1833,14 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
1817
1833
struct amdgpu_bo_va_mapping * before , * after , * tmp , * next ;
1818
1834
LIST_HEAD (removed );
1819
1835
uint64_t eaddr ;
1836
+ int r ;
1837
+
1838
+ r = amdgpu_vm_verify_parameters (adev , NULL , saddr , 0 , size );
1839
+ if (r )
1840
+ return r ;
1820
1841
1821
- eaddr = saddr + size - 1 ;
1822
1842
saddr /= AMDGPU_GPU_PAGE_SIZE ;
1823
- eaddr /= AMDGPU_GPU_PAGE_SIZE ;
1843
+ eaddr = saddr + ( size - 1 ) / AMDGPU_GPU_PAGE_SIZE ;
1824
1844
1825
1845
/* Allocate all the needed memory */
1826
1846
before = kzalloc (sizeof (* before ), GFP_KERNEL );
0 commit comments