Skip to content

Commit 8c0bc7d

Browse files
committed
drm/vmwgfx: Fix possible invalid drm gem put calls
jira VULN-8161 cve CVE-2023-5633 commit-author Zack Rusin <zackr@vmware.com> commit f9e96bf 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@vmware.com> Reported-by: Ian Forbes <iforbes@vmware.com> Fixes: 9ef8d83 ("drm/vmwgfx: Do not drop the reference to the handle too soon") Cc: <stable@vger.kernel.org> # v6.4+ Reviewed-by: Maaz Mombasawala<mombasawalam@vmware.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230818041301.407636-1-zack@kde.org (cherry picked from commit f9e96bf) Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
1 parent ee76bdd commit 8c0bc7d

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
@@ -512,10 +512,9 @@ static int vmw_user_bo_synccpu_release(struct drm_file *filp,
512512
if (!(flags & drm_vmw_synccpu_allow_cs)) {
513513
atomic_dec(&vmw_bo->cpu_writers);
514514
}
515-
ttm_bo_put(&vmw_bo->tbo);
515+
vmw_user_bo_unref(vmw_bo);
516516
}
517517

518-
drm_gem_object_put(&vmw_bo->tbo.base);
519518
return ret;
520519
}
521520

@@ -555,8 +554,7 @@ int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data,
555554
return ret;
556555

557556
ret = vmw_user_bo_synccpu_grab(vbo, arg->flags);
558-
vmw_bo_unreference(&vbo);
559-
drm_gem_object_put(&vbo->tbo.base);
557+
vmw_user_bo_unref(vbo);
560558
if (unlikely(ret != 0)) {
561559
if (ret == -ERESTARTSYS || ret == -EBUSY)
562560
return -EBUSY;

drivers/gpu/drm/vmwgfx/vmwgfx_bo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,14 @@ static inline struct vmw_bo *vmw_bo_reference(struct vmw_bo *buf)
195195
return buf;
196196
}
197197

198+
static inline void vmw_user_bo_unref(struct vmw_bo *vbo)
199+
{
200+
if (vbo) {
201+
ttm_bo_put(&vbo->tbo);
202+
drm_gem_object_put(&vbo->tbo.base);
203+
}
204+
}
205+
198206
static inline struct vmw_bo *to_vmw_bo(struct drm_gem_object *gobj)
199207
{
200208
return container_of((gobj), struct vmw_bo, tbo.base);

drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,8 +1164,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv,
11641164
}
11651165
vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_MOB, VMW_BO_DOMAIN_MOB);
11661166
ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo);
1167-
ttm_bo_put(&vmw_bo->tbo);
1168-
drm_gem_object_put(&vmw_bo->tbo.base);
1167+
vmw_user_bo_unref(vmw_bo);
11691168
if (unlikely(ret != 0))
11701169
return ret;
11711170

@@ -1221,8 +1220,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
12211220
vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM,
12221221
VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM);
12231222
ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo);
1224-
ttm_bo_put(&vmw_bo->tbo);
1225-
drm_gem_object_put(&vmw_bo->tbo.base);
1223+
vmw_user_bo_unref(vmw_bo);
12261224
if (unlikely(ret != 0))
12271225
return ret;
12281226

drivers/gpu/drm/vmwgfx/vmwgfx_kms.c

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

17261726
err_out:
17271727
/* vmw_user_lookup_handle takes one ref so does new_fb */
1728-
if (bo) {
1729-
vmw_bo_unreference(&bo);
1730-
drm_gem_object_put(&bo->tbo.base);
1731-
}
1728+
if (bo)
1729+
vmw_user_bo_unref(bo);
17321730
if (surface)
17331731
vmw_surface_unreference(&surface);
17341732

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->tbo.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
@@ -809,8 +809,7 @@ static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv,
809809
shader_type, num_input_sig,
810810
num_output_sig, tfile, shader_handle);
811811
out_bad_arg:
812-
vmw_bo_unreference(&buffer);
813-
drm_gem_object_put(&buffer->tbo.base);
812+
vmw_user_bo_unref(buffer);
814813
return ret;
815814
}
816815

0 commit comments

Comments
 (0)