From: Akash Goel Date: Mon, 13 Apr 2026 08:02:53 +0000 (+0100) Subject: drm/panthor: Avoid potential UAF due to memory reclaim X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=aa33054b314e3c78e082dcd58895c2cb64c9f2c7;p=thirdparty%2Fkernel%2Flinux.git drm/panthor: Avoid potential UAF due to memory reclaim Recent changes to add shrinker support introduced a use after free vulnerability. When a BO is evicted from the shrinker callback, all its CPU and GPU mappings are invalidated. It can happen that another GPU mapping is created for the BO after the eviction. Because of the new GPU mapping, BO will be added back to one of the reclaim list but the state of corresponding vm_bo will not be changed. If vm_bo remains in evicted state and shrinker callback is invoked again then the new GPU mapping won't be invalidated. As a result the backing pages, which were acquired on the creation of new GPU mapping, can get reclaimed and reused whilst they are still mapped to the GPU. To prevent the use after free possibility, this commit removes the evicted check for vm_bo so that all GPU mappings are checked for invalidation. v2: - Update comment and add a newline in panthor_vm_evict_bo_mappings_locked(). Fixes: fb42964e2a76 ("drm/panthor: Add a GEM shrinker") Suggested-by: Boris Brezillon Signed-off-by: Akash Goel Reviewed-by: Boris Brezillon Reviewed-by: Steven Price Reviewed-by: Liviu Dudau Signed-off-by: Steven Price Link: https://patch.msgid.link/20260413080253.1288157-1-akash.goel@arm.com --- diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c index a7ee14986849..452d0b6d4668 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -2377,14 +2377,20 @@ int panthor_vm_evict_bo_mappings_locked(struct panthor_gem_object *bo) struct panthor_vm *vm = container_of(vm_bo->vm, struct panthor_vm, base); struct drm_gpuva *va; - /* Skip already evicted GPU mappings. */ - if (vm_bo->evicted) - continue; - if (!mutex_trylock(&vm->op_lock)) return -EDEADLK; - drm_gpuvm_bo_evict(vm_bo, true); + /* It can be that the vm_bo was already evicted but a new + * mapping pointing to this BO got created in the meantime, + * thus turning the vm_bo in partially evicted state. In that case + * we don't call drm_gpuvm_bo_evict() again because this would + * mess up with the internal gpuvm lists, but we do walk the + * VAs on this vm_bo to make sure the non-evicted ones are + * torn down. + */ + if (!vm_bo->evicted) + drm_gpuvm_bo_evict(vm_bo, true); + drm_gpuvm_bo_for_each_va(va, vm_bo) { struct panthor_vma *vma = container_of(va, struct panthor_vma, base);