--- a/sys/dev/drm/amd/amdgpu/amdgpu_gem.c +++ b/sys/dev/drm/amd/amdgpu/amdgpu_gem.c @@ -633,6 +633,28 @@ bo_va = NULL; } + /* + * Validate the mapping before allocating page tables for it. + * amdgpu_vm_alloc_pts() below commits page-table BOs for the whole + * [va_address, va_address + map_size) range; when amdgpu_vm_bo_map() + * then rejects the mapping (bad offset_in_bo / map_size), those page + * tables stay allocated until VM teardown. An unprivileged render + * node client can pin ~(map_size >> 18) bytes of GTT per failed + * ioctl with no backing BO, and repeat until GTT is exhausted. + */ + if (args->operation == AMDGPU_VA_OP_MAP || + args->operation == AMDGPU_VA_OP_REPLACE) { + if (!args->map_size || (args->map_size & AMDGPU_GPU_PAGE_MASK) || + (args->offset_in_bo & AMDGPU_GPU_PAGE_MASK) || + args->va_address + args->map_size - 1 < args->va_address || + args->offset_in_bo + args->map_size < args->offset_in_bo || + (abo && args->offset_in_bo + args->map_size > + amdgpu_bo_size(abo))) { + r = -EINVAL; + goto error_backoff; + } + } + switch (args->operation) { case AMDGPU_VA_OP_MAP: r = amdgpu_vm_alloc_pts(adev, bo_va->base.vm, args->va_address,