[PATCH] drm/msm: Fix vm_bo use-after-free in with_vm_locks()
From: Wentao Liang
Date: Wed Sep 16 2026 - 15:10:26 EST
The unwind loop drops the vm_bo reference taken while locking before
advancing to the next entry. drm_gpuvm_bo_put() may drop the last
reference, removing and freeing the vm_bo, after which the plain list
iterator dereferences freed memory to advance.
Use the safe iterator, which saves the next entry before the body runs.
Fixes: fe4952b5f27cca5d ("drm/msm: Convert vm locking")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Wentao Liang <vulab@xxxxxxxxxxx>
---
drivers/gpu/drm/msm/msm_gem_shrinker.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/msm_gem_shrinker.c b/drivers/gpu/drm/msm/msm_gem_shrinker.c
index c8dda2b68cff..27b45165b213 100644
--- a/drivers/gpu/drm/msm/msm_gem_shrinker.c
+++ b/drivers/gpu/drm/msm/msm_gem_shrinker.c
@@ -51,6 +51,7 @@ with_vm_locks(void (*fn)(struct drm_gem_object *obj),
* success paths
*/
struct drm_gpuvm_bo *vm_bo, *last_locked = NULL;
+ struct drm_gpuvm_bo *next;
bool locked = true;
drm_gem_for_each_gpuvm_bo (vm_bo, obj) {
@@ -82,7 +83,7 @@ with_vm_locks(void (*fn)(struct drm_gem_object *obj),
out_unlock:
if (last_locked) {
- drm_gem_for_each_gpuvm_bo (vm_bo, obj) {
+ drm_gem_for_each_gpuvm_bo_safe(vm_bo, next, obj) {
struct dma_resv *resv = drm_gpuvm_resv(vm_bo->vm);
if (resv == obj->resv)
--
2.34.1