@@ -2201,6 +2201,37 @@ static void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev,
22012201 trace_amdgpu_vm_bo_map (bo_va , mapping );
22022202}
22032203
2204+ /* Validate operation parameters to prevent potential abuse */
2205+ static int amdgpu_vm_verify_parameters (struct amdgpu_device * adev ,
2206+ struct amdgpu_bo * bo ,
2207+ uint64_t saddr ,
2208+ uint64_t offset ,
2209+ uint64_t size )
2210+ {
2211+ uint64_t tmp , lpfn ;
2212+
2213+ if (saddr & AMDGPU_GPU_PAGE_MASK
2214+ || offset & AMDGPU_GPU_PAGE_MASK
2215+ || size & AMDGPU_GPU_PAGE_MASK )
2216+ return - EINVAL ;
2217+
2218+ if (check_add_overflow (saddr , size , & tmp )
2219+ || check_add_overflow (offset , size , & tmp )
2220+ || size == 0 /* which also leads to end < begin */ )
2221+ return - EINVAL ;
2222+
2223+ /* make sure object fit at this offset */
2224+ if (bo && offset + size > amdgpu_bo_size (bo ))
2225+ return - EINVAL ;
2226+
2227+ /* Ensure last pfn not exceed max_pfn */
2228+ lpfn = (saddr + size - 1 ) >> AMDGPU_GPU_PAGE_SHIFT ;
2229+ if (lpfn >= adev -> vm_manager .max_pfn )
2230+ return - EINVAL ;
2231+
2232+ return 0 ;
2233+ }
2234+
22042235/**
22052236 * amdgpu_vm_bo_map - map bo inside a vm
22062237 *
@@ -2227,21 +2258,14 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
22272258 struct amdgpu_bo * bo = bo_va -> base .bo ;
22282259 struct amdgpu_vm * vm = bo_va -> base .vm ;
22292260 uint64_t eaddr ;
2261+ int r ;
22302262
2231- /* validate the parameters */
2232- if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK )
2233- return - EINVAL ;
2234- if (saddr + size <= saddr || offset + size <= offset )
2235- return - EINVAL ;
2236-
2237- /* make sure object fit at this offset */
2238- eaddr = saddr + size - 1 ;
2239- if ((bo && offset + size > amdgpu_bo_size (bo )) ||
2240- (eaddr >= adev -> vm_manager .max_pfn << AMDGPU_GPU_PAGE_SHIFT ))
2241- return - EINVAL ;
2263+ r = amdgpu_vm_verify_parameters (adev , bo , saddr , offset , size );
2264+ if (r )
2265+ return r ;
22422266
22432267 saddr /= AMDGPU_GPU_PAGE_SIZE ;
2244- eaddr /= AMDGPU_GPU_PAGE_SIZE ;
2268+ eaddr = saddr + ( size - 1 ) / AMDGPU_GPU_PAGE_SIZE ;
22452269
22462270 tmp = amdgpu_vm_it_iter_first (& vm -> va , saddr , eaddr );
22472271 if (tmp ) {
@@ -2294,17 +2318,9 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
22942318 uint64_t eaddr ;
22952319 int r ;
22962320
2297- /* validate the parameters */
2298- if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK )
2299- return - EINVAL ;
2300- if (saddr + size <= saddr || offset + size <= offset )
2301- return - EINVAL ;
2302-
2303- /* make sure object fit at this offset */
2304- eaddr = saddr + size - 1 ;
2305- if ((bo && offset + size > amdgpu_bo_size (bo )) ||
2306- (eaddr >= adev -> vm_manager .max_pfn << AMDGPU_GPU_PAGE_SHIFT ))
2307- return - EINVAL ;
2321+ r = amdgpu_vm_verify_parameters (adev , bo , saddr , offset , size );
2322+ if (r )
2323+ return r ;
23082324
23092325 /* Allocate all the needed memory */
23102326 mapping = kmalloc (sizeof (* mapping ), GFP_KERNEL );
@@ -2318,7 +2334,7 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
23182334 }
23192335
23202336 saddr /= AMDGPU_GPU_PAGE_SIZE ;
2321- eaddr /= AMDGPU_GPU_PAGE_SIZE ;
2337+ eaddr = saddr + ( size - 1 ) / AMDGPU_GPU_PAGE_SIZE ;
23222338
23232339 mapping -> start = saddr ;
23242340 mapping -> last = eaddr ;
@@ -2405,10 +2421,14 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
24052421 struct amdgpu_bo_va_mapping * before , * after , * tmp , * next ;
24062422 LIST_HEAD (removed );
24072423 uint64_t eaddr ;
2424+ int r ;
2425+
2426+ r = amdgpu_vm_verify_parameters (adev , NULL , saddr , 0 , size );
2427+ if (r )
2428+ return r ;
24082429
2409- eaddr = saddr + size - 1 ;
24102430 saddr /= AMDGPU_GPU_PAGE_SIZE ;
2411- eaddr /= AMDGPU_GPU_PAGE_SIZE ;
2431+ eaddr = saddr + ( size - 1 ) / AMDGPU_GPU_PAGE_SIZE ;
24122432
24132433 /* Allocate all the needed memory */
24142434 before = kzalloc (sizeof (* before ), GFP_KERNEL );
0 commit comments