Re: [PATCH] drm/vmwgfx: Fix possible invalid drm gem put calls

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Martin Krastev <krastevm@xxxxxxxxxx>


LGTM!

Reviewed-by: Martin Krastev <krastevm@xxxxxxxxxx>


Regards,

Martin


On 18 Aug 2023 04:13:14, Zack Rusin wrote:

>From: Zack Rusin <zackr@xxxxxxxxxx>
>
>vmw_bo_unreference sets the input buffer to null on exit, resulting in
>null ptr deref's on the subsequent drm gem put calls.
>
>This went unnoticed because only very old userspace would be exercising
>those paths but it wouldn't be hard to hit on old distros with brand
>new kernels.
>
>Introduce a new function that abstracts unrefing of user bo's to make
>the code cleaner and more explicit.
>
>Signed-off-by: Zack Rusin <zackr@xxxxxxxxxx>
>Reported-by: Ian Forbes <iforbes@xxxxxxxxxx>
>Fixes: 9ef8d83e8e25 ("drm/vmwgfx: Do not drop the reference to the handle too soon")
>Cc: <stable@xxxxxxxxxxxxxxx> # v6.4+
>---
> drivers/gpu/drm/vmwgfx/vmwgfx_bo.c      | 6 ++----
> drivers/gpu/drm/vmwgfx/vmwgfx_bo.h      | 8 ++++++++
> drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 6 ++----
> drivers/gpu/drm/vmwgfx/vmwgfx_kms.c     | 6 ++----
> drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c | 3 +--
> drivers/gpu/drm/vmwgfx/vmwgfx_shader.c  | 3 +--
> 6 files changed, 16 insertions(+), 16 deletions(-)
>
>diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
>index 82094c137855..c43853597776 100644
>--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
>+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
>@@ -497,10 +497,9 @@ static int vmw_user_bo_synccpu_release(struct drm_file *filp,
>                 if (!(flags & drm_vmw_synccpu_allow_cs)) {
> atomic_dec(&vmw_bo->cpu_writers);
>                 }
>-               ttm_bo_put(&vmw_bo->tbo);
>+               vmw_user_bo_unref(vmw_bo);
>         }
>
>-       drm_gem_object_put(&vmw_bo->tbo.base);
>         return ret;
> }
>
>@@ -540,8 +539,7 @@ int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data,
>                         return ret;
>
>                 ret = vmw_user_bo_synccpu_grab(vbo, arg->flags);
>-               vmw_bo_unreference(&vbo);
>-               drm_gem_object_put(&vbo->tbo.base);
>+               vmw_user_bo_unref(vbo);
>                 if (unlikely(ret != 0)) {
>                         if (ret == -ERESTARTSYS || ret == -EBUSY)
>                                 return -EBUSY;
>diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
>index 50a836e70994..1d433fceed3d 100644
>--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
>+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
>@@ -195,6 +195,14 @@ static inline struct vmw_bo *vmw_bo_reference(struct vmw_bo *buf)
>         return buf;
> }
>
>+static inline void vmw_user_bo_unref(struct vmw_bo *vbo)
>+{
>+       if (vbo) {
>+               ttm_bo_put(&vbo->tbo);
>+               drm_gem_object_put(&vbo->tbo.base);
>+       }
>+}
>+
> static inline struct vmw_bo *to_vmw_bo(struct drm_gem_object *gobj)
> {
>         return container_of((gobj), struct vmw_bo, tbo.base);
>diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
>index 6b9aa2b4ef54..25b96821df0f 100644
>--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
>+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
>@@ -1164,8 +1164,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv,
>         }
>         vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_MOB, VMW_BO_DOMAIN_MOB);
>         ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo);
>-       ttm_bo_put(&vmw_bo->tbo);
>-       drm_gem_object_put(&vmw_bo->tbo.base);
>+       vmw_user_bo_unref(vmw_bo);
>         if (unlikely(ret != 0))
>                 return ret;
>
>@@ -1221,8 +1220,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, >         vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM,
>                              VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM);
>         ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo);
>-       ttm_bo_put(&vmw_bo->tbo);
>-       drm_gem_object_put(&vmw_bo->tbo.base);
>+       vmw_user_bo_unref(vmw_bo);
>         if (unlikely(ret != 0))
>                 return ret;
>
>diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
>index b62207be3363..1489ad73c103 100644
>--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
>+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
>@@ -1665,10 +1665,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
>
> err_out:
>         /* vmw_user_lookup_handle takes one ref so does new_fb */
>-       if (bo) {
>-               vmw_bo_unreference(&bo);
>-               drm_gem_object_put(&bo->tbo.base);
>-       }
>+       if (bo)
>+               vmw_user_bo_unref(bo);
>         if (surface)
>                 vmw_surface_unreference(&surface);
>
>diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
>index 7e112319a23c..fb85f244c3d0 100644
>--- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
>+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
>@@ -451,8 +451,7 @@ int vmw_overlay_ioctl(struct drm_device *dev, void *data,
>
>         ret = vmw_overlay_update_stream(dev_priv, buf, arg, true);
>
>-       vmw_bo_unreference(&buf);
>-       drm_gem_object_put(&buf->tbo.base);
>+       vmw_user_bo_unref(buf);
>
> out_unlock:
>         mutex_unlock(&overlay->mutex);
>diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
>index e7226db8b242..1e81ff2422cf 100644
>--- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
>+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
>@@ -809,8 +809,7 @@ static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv,
>                                     shader_type, num_input_sig,
>                                     num_output_sig, tfile, shader_handle);
> out_bad_arg:
>-       vmw_bo_unreference(&buffer);
>-       drm_gem_object_put(&buffer->tbo.base);
>+       vmw_user_bo_unref(buffer);
>         return ret;
> }
>
>--
>2.39.2




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux