@@ -1613,6 +1613,37 @@ static void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev,
16131613 trace_amdgpu_vm_bo_map (bo_va , mapping );
16141614}
16151615
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+
16161647/**
16171648 * amdgpu_vm_bo_map - map bo inside a vm
16181649 *
@@ -1639,21 +1670,14 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
16391670 struct amdgpu_bo * bo = bo_va -> base .bo ;
16401671 struct amdgpu_vm * vm = bo_va -> base .vm ;
16411672 uint64_t eaddr ;
1673+ int r ;
16421674
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 ;
16541678
16551679 saddr /= AMDGPU_GPU_PAGE_SIZE ;
1656- eaddr /= AMDGPU_GPU_PAGE_SIZE ;
1680+ eaddr = saddr + ( size - 1 ) / AMDGPU_GPU_PAGE_SIZE ;
16571681
16581682 tmp = amdgpu_vm_it_iter_first (& vm -> va , saddr , eaddr );
16591683 if (tmp ) {
@@ -1706,17 +1730,9 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
17061730 uint64_t eaddr ;
17071731 int r ;
17081732
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 ;
17201736
17211737 /* Allocate all the needed memory */
17221738 mapping = kmalloc (sizeof (* mapping ), GFP_KERNEL );
@@ -1730,7 +1746,7 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
17301746 }
17311747
17321748 saddr /= AMDGPU_GPU_PAGE_SIZE ;
1733- eaddr /= AMDGPU_GPU_PAGE_SIZE ;
1749+ eaddr = saddr + ( size - 1 ) / AMDGPU_GPU_PAGE_SIZE ;
17341750
17351751 mapping -> start = saddr ;
17361752 mapping -> last = eaddr ;
@@ -1817,10 +1833,14 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
18171833 struct amdgpu_bo_va_mapping * before , * after , * tmp , * next ;
18181834 LIST_HEAD (removed );
18191835 uint64_t eaddr ;
1836+ int r ;
1837+
1838+ r = amdgpu_vm_verify_parameters (adev , NULL , saddr , 0 , size );
1839+ if (r )
1840+ return r ;
18201841
1821- eaddr = saddr + size - 1 ;
18221842 saddr /= AMDGPU_GPU_PAGE_SIZE ;
1823- eaddr /= AMDGPU_GPU_PAGE_SIZE ;
1843+ eaddr = saddr + ( size - 1 ) / AMDGPU_GPU_PAGE_SIZE ;
18241844
18251845 /* Allocate all the needed memory */
18261846 before = kzalloc (sizeof (* before ), GFP_KERNEL );
0 commit comments