Skip to content

Commit 6fef2d4

Browse files
xinhui panalexdeucher
authored andcommitted
drm/amdgpu: validate the parameters of bo mapping operations more clearly
Verify the parameters of amdgpu_vm_bo_(map/replace_map/clearing_mappings) in one common place. Fixes: dc54d3d ("drm/amdgpu: implement AMDGPU_VA_OP_CLEAR v2") Cc: [email protected] Reported-by: Vlad Stolyarov <[email protected]> Suggested-by: Christian König <[email protected]> Signed-off-by: xinhui pan <[email protected]> Reviewed-by: Christian König <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 91f10a3 commit 6fef2d4

File tree

1 file changed

+46
-26
lines changed

1 file changed

+46
-26
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)