drm/vmwgfx: Stop accessing buffer objects which failed init
authorZack Rusin <zackr@vmware.com>
Wed, 8 Feb 2023 18:00:50 +0000 (13:00 -0500)
committerZack Rusin <zackr@vmware.com>
Wed, 15 Feb 2023 03:05:21 +0000 (22:05 -0500)
ttm_bo_init_reserved on failure puts the buffer object back which
causes it to be deleted, but kfree was still being called on the same
buffer in vmw_bo_create leading to a double free.

After the double free the vmw_gem_object_create_with_handle was
setting the gem function objects before checking the return status
of vmw_bo_create leading to null pointer access.

Fix the entire path by relaying on ttm_bo_init_reserved to delete the
buffer objects on failure and making sure the return status is checked
before setting the gem function objects on the buffer object.

Signed-off-by: Zack Rusin <zackr@vmware.com>
Fixes: 8afa13a0583f ("drm/vmwgfx: Implement DRIVER_GEM")
Reviewed-by: Maaz Mombasawala <mombasawalam@vmware.com>
Reviewed-by: Martin Krastev <krastevm@vmware.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230208180050.2093426-1-zack@kde.org
drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
drivers/gpu/drm/vmwgfx/vmwgfx_gem.c

index ee8f87d..7a00314 100644 (file)
@@ -416,13 +416,15 @@ int vmw_bo_create(struct vmw_private *vmw,
                return -ENOMEM;
        }
 
+       /*
+        * vmw_bo_init will delete the *p_bo object if it fails
+        */
        ret = vmw_bo_init(vmw, *p_bo, params, vmw_bo_free);
        if (unlikely(ret != 0))
                goto out_error;
 
        return ret;
 out_error:
-       kfree(*p_bo);
        *p_bo = NULL;
        return ret;
 }
index f042e22..51bd1f8 100644 (file)
@@ -127,11 +127,11 @@ int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv,
        };
 
        ret = vmw_bo_create(dev_priv, &params, p_vbo);
-
-       (*p_vbo)->tbo.base.funcs = &vmw_gem_object_funcs;
        if (ret != 0)
                goto out_no_bo;
 
+       (*p_vbo)->tbo.base.funcs = &vmw_gem_object_funcs;
+
        ret = drm_gem_handle_create(filp, &(*p_vbo)->tbo.base, handle);
        /* drop reference from allocate - handle holds it now */
        drm_gem_object_put(&(*p_vbo)->tbo.base);