drm/msm: Fix obj leak in VM_BIND error path

If we fail a handle-lookup part way thru, we need to drop the already
obtained obj references.

Fixes: 2e6a8a1fe2 ("drm/msm: Add VM_BIND ioctl")
Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
Tested-by: Connor Abbott <cwabbott0@gmail.com>
Patchwork: https://patchwork.freedesktop.org/patch/669784/
This commit is contained in:
Rob Clark
2025-08-20 17:04:25 -07:00
parent 9be5c47908
commit 278f890443

View File

@@ -1023,6 +1023,7 @@ vm_bind_job_lookup_ops(struct msm_vm_bind_job *job, struct drm_msm_vm_bind *args
struct drm_device *dev = job->vm->drm;
int ret = 0;
int cnt = 0;
int i = -1;
if (args->nr_ops == 1) {
/* Single op case, the op is inlined: */
@@ -1056,11 +1057,12 @@ vm_bind_job_lookup_ops(struct msm_vm_bind_job *job, struct drm_msm_vm_bind *args
spin_lock(&file->table_lock);
for (unsigned i = 0; i < args->nr_ops; i++) {
for (i = 0; i < args->nr_ops; i++) {
struct msm_vm_bind_op *op = &job->ops[i];
struct drm_gem_object *obj;
if (!job->ops[i].handle) {
job->ops[i].obj = NULL;
if (!op->handle) {
op->obj = NULL;
continue;
}
@@ -1068,15 +1070,15 @@ vm_bind_job_lookup_ops(struct msm_vm_bind_job *job, struct drm_msm_vm_bind *args
* normally use drm_gem_object_lookup(), but for bulk lookup
* all under single table_lock just hit object_idr directly:
*/
obj = idr_find(&file->object_idr, job->ops[i].handle);
obj = idr_find(&file->object_idr, op->handle);
if (!obj) {
ret = UERR(EINVAL, dev, "invalid handle %u at index %u\n", job->ops[i].handle, i);
ret = UERR(EINVAL, dev, "invalid handle %u at index %u\n", op->handle, i);
goto out_unlock;
}
drm_gem_object_get(obj);
job->ops[i].obj = obj;
op->obj = obj;
cnt++;
}
@@ -1085,6 +1087,17 @@ vm_bind_job_lookup_ops(struct msm_vm_bind_job *job, struct drm_msm_vm_bind *args
out_unlock:
spin_unlock(&file->table_lock);
if (ret) {
for (; i >= 0; i--) {
struct msm_vm_bind_op *op = &job->ops[i];
if (!op->obj)
continue;
drm_gem_object_put(op->obj);
op->obj = NULL;
}
}
out:
return ret;
}