On error the bo would still be attached to the entry, while the bo gets
unref'ed. Later when the VM is torn down the bo would be accessed again
in order to attempt a cleanup, resulting in a use-after-free.

Fixes: 009f401fb98b ("drm/amdgpu: move amdgpu_vm_bo_update() call into correct 
location")
Signed-off-by: Benjamin Cheng <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
index c73eb416c0e2..a66aac73e835 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
@@ -502,6 +502,8 @@ int amdgpu_vm_pt_create(struct amdgpu_device *adev, struct 
amdgpu_vm *vm,
        return 0;
 }
 
+static void amdgpu_vm_pt_free(struct amdgpu_vm_bo_base *entry);
+
 /**
  * amdgpu_vm_pt_alloc - Allocate a specific page table
  *
@@ -544,8 +546,10 @@ static int amdgpu_vm_pt_alloc(struct 
amdgpu_vm_update_params *p,
        pt_bo->parent = amdgpu_bo_ref(cursor->parent->bo);
        amdgpu_vm_bo_base_init(entry, p->vm, pt_bo);
        r = amdgpu_vm_pt_clear(p->adev, p->vm, pt, p->immediate);
-       if (r)
-               goto error_unpin;
+       if (r) {
+               amdgpu_vm_pt_free(entry);
+               return r;
+       }
 
        return 0;
 
-- 
2.56.0

Reply via email to