Skip to content

Commit 5a4087a

Browse files
zackrgregkh
authored andcommitted
drm/vmwgfx: Fix possible invalid drm gem put calls
commit f9e96bf upstream. 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 <[email protected]> Reported-by: Ian Forbes <[email protected]> Fixes: 9ef8d83 ("drm/vmwgfx: Do not drop the reference to the handle too soon") Cc: <[email protected]> # v6.4+ Reviewed-by: Maaz Mombasawala<[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Signed-off-by: Jocelyn Falempe <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent a71776b commit 5a4087a

File tree

6 files changed

+16
-16
lines changed

6 files changed

+16
-16
lines changed

drivers/gpu/drm/vmwgfx/vmwgfx_bo.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -595,10 +595,9 @@ static int vmw_user_bo_synccpu_release(struct drm_file *filp,
595595
if (!(flags & drm_vmw_synccpu_allow_cs)) {
596596
atomic_dec(&vmw_bo->cpu_writers);
597597
}
598-
ttm_bo_put(&vmw_bo->base);
598+
vmw_user_bo_unref(vmw_bo);
599599
}
600600

601-
drm_gem_object_put(&vmw_bo->base.base);
602601
return ret;
603602
}
604603

@@ -638,8 +637,7 @@ int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data,
638637
return ret;
639638

640639
ret = vmw_user_bo_synccpu_grab(vbo, arg->flags);
641-
vmw_bo_unreference(&vbo);
642-
drm_gem_object_put(&vbo->base.base);
640+
vmw_user_bo_unref(vbo);
643641
if (unlikely(ret != 0)) {
644642
if (ret == -ERESTARTSYS || ret == -EBUSY)
645643
return -EBUSY;

drivers/gpu/drm/vmwgfx/vmwgfx_drv.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,6 +1600,14 @@ vmw_bo_reference(struct vmw_buffer_object *buf)
16001600
return buf;
16011601
}
16021602

1603+
static inline void vmw_user_bo_unref(struct vmw_buffer_object *vbo)
1604+
{
1605+
if (vbo) {
1606+
ttm_bo_put(&vbo->base);
1607+
drm_gem_object_put(&vbo->base.base);
1608+
}
1609+
}
1610+
16031611
static inline void vmw_fifo_resource_inc(struct vmw_private *dev_priv)
16041612
{
16051613
atomic_inc(&dev_priv->num_fifo_resources);

drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,8 +1159,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv,
11591159
return PTR_ERR(vmw_bo);
11601160
}
11611161
ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, true, false);
1162-
ttm_bo_put(&vmw_bo->base);
1163-
drm_gem_object_put(&vmw_bo->base.base);
1162+
vmw_user_bo_unref(vmw_bo);
11641163
if (unlikely(ret != 0))
11651164
return ret;
11661165

@@ -1214,8 +1213,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
12141213
return PTR_ERR(vmw_bo);
12151214
}
12161215
ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, false, false);
1217-
ttm_bo_put(&vmw_bo->base);
1218-
drm_gem_object_put(&vmw_bo->base.base);
1216+
vmw_user_bo_unref(vmw_bo);
12191217
if (unlikely(ret != 0))
12201218
return ret;
12211219

drivers/gpu/drm/vmwgfx/vmwgfx_kms.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,10 +1599,8 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
15991599

16001600
err_out:
16011601
/* vmw_user_lookup_handle takes one ref so does new_fb */
1602-
if (bo) {
1603-
vmw_bo_unreference(&bo);
1604-
drm_gem_object_put(&bo->base.base);
1605-
}
1602+
if (bo)
1603+
vmw_user_bo_unref(bo);
16061604
if (surface)
16071605
vmw_surface_unreference(&surface);
16081606

drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,7 @@ int vmw_overlay_ioctl(struct drm_device *dev, void *data,
457457

458458
ret = vmw_overlay_update_stream(dev_priv, buf, arg, true);
459459

460-
vmw_bo_unreference(&buf);
461-
drm_gem_object_put(&buf->base.base);
460+
vmw_user_bo_unref(buf);
462461

463462
out_unlock:
464463
mutex_unlock(&overlay->mutex);

drivers/gpu/drm/vmwgfx/vmwgfx_shader.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -806,8 +806,7 @@ static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv,
806806
shader_type, num_input_sig,
807807
num_output_sig, tfile, shader_handle);
808808
out_bad_arg:
809-
vmw_bo_unreference(&buffer);
810-
drm_gem_object_put(&buffer->base.base);
809+
vmw_user_bo_unref(buffer);
811810
return ret;
812811
}
813812

0 commit comments

Comments
 (0)