[PATCH] drm/msm: fix refcount leak in msm_gem_vm_sm_step_remap()

Wentao Liang posted 1 patch 1 day, 13 hours ago
drivers/gpu/drm/msm/msm_gem_vma.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
[PATCH] drm/msm: fix refcount leak in msm_gem_vm_sm_step_remap()
Posted by Wentao Liang 1 day, 13 hours ago
In msm_gem_vm_sm_step_remap(), a temporary reference on vm_bo is
acquired via drm_gpuvm_bo_get() to keep the object alive during
vma close and creation. On success, the reference is released with
drm_gpuvm_bo_put(). However, when vma_from_op() fails for prev_vma
or next_vma, the function returns directly without releasing the
reference, causing a leak.

Fix by converting the error returns to a common error path that
releases the temporary reference before returning.

Cc: stable@vger.kernel.org
Fixes: 2e6a8a1fe2b2 ("drm/msm: Add VM_BIND ioctl")
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
---
 drivers/gpu/drm/msm/msm_gem_vma.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c
index 1a952b171ed7..69289bea7a66 100644
--- a/drivers/gpu/drm/msm/msm_gem_vma.c
+++ b/drivers/gpu/drm/msm/msm_gem_vma.c
@@ -602,8 +602,10 @@ msm_gem_vm_sm_step_remap(struct drm_gpuva_op *op, void *arg)
 
 	if (op->remap.prev) {
 		prev_vma = vma_from_op(arg, op->remap.prev);
-		if (WARN_ON(IS_ERR(prev_vma)))
-			return PTR_ERR(prev_vma);
+		if (WARN_ON(IS_ERR(prev_vma))) {
+			ret = PTR_ERR(prev_vma);
+			goto drop_ref;
+		}
 
 		vm_dbg("prev_vma: %p:%p: %016llx %016llx", vm, prev_vma, prev_vma->va.addr, prev_vma->va.range);
 		to_msm_vma(prev_vma)->mapped = mapped;
@@ -612,8 +614,10 @@ msm_gem_vm_sm_step_remap(struct drm_gpuva_op *op, void *arg)
 
 	if (op->remap.next) {
 		next_vma = vma_from_op(arg, op->remap.next);
-		if (WARN_ON(IS_ERR(next_vma)))
-			return PTR_ERR(next_vma);
+		if (WARN_ON(IS_ERR(next_vma))) {
+			ret = PTR_ERR(next_vma);
+			goto drop_ref;
+		}
 
 		vm_dbg("next_vma: %p:%p: %016llx %016llx", vm, next_vma, next_vma->va.addr, next_vma->va.range);
 		to_msm_vma(next_vma)->mapped = mapped;
@@ -623,6 +627,7 @@ msm_gem_vm_sm_step_remap(struct drm_gpuva_op *op, void *arg)
 	if (!mapped)
 		drm_gpuvm_bo_evict(vm_bo, true);
 
+drop_ref:
 	/* Drop the previous ref: */
 	drm_gpuvm_bo_put(vm_bo);
 
-- 
2.34.1