Skip to content

Commit 276cd6a

Browse files
committed
drm/vmwgfx: Cleanup the cursor snooping code
jira VULN-8161 cve CVE-2023-5633 commit-author Zack Rusin <zackr@vmware.com> commit da7ffb9 Cursor snooping depended on implicit size and format which made debugging quite difficult. Make the code easier to following by making everything explicit and instead of using magic numbers predefine all the parameters the code depends on. Also fixes incorrectly computed pitches for non-aligned cursor snoops. Fix which has no practical effect because non-aligned cursor snoops are not used by the X11 driver and Wayland cursors will go through mob cursors, instead of surface dma's. Signed-off-by: Zack Rusin <zackr@vmware.com> Reviewed-by: Michael Banack <banackm@vmware.com> Reviewed-by: Martin Krastev <krastevm@vmware.com> Link: https://patchwork.freedesktop.org/patch/msgid/20221026031936.1004280-2-zack@kde.org (cherry picked from commit da7ffb9) Signed-off-by: Sultan Alsawaf <sultan@ciq.com>
1 parent 6bedcf1 commit 276cd6a

File tree

3 files changed

+30
-17
lines changed

3 files changed

+30
-17
lines changed

drivers/gpu/drm/vmwgfx/vmwgfx_drv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@
9898
#define VMW_RES_SHADER ttm_driver_type4
9999
#define VMW_RES_HT_ORDER 12
100100

101+
#define VMW_CURSOR_SNOOP_FORMAT SVGA3D_A8R8G8B8
102+
#define VMW_CURSOR_SNOOP_WIDTH 64
103+
#define VMW_CURSOR_SNOOP_HEIGHT 64
104+
101105
#define MKSSTAT_CAPACITY_LOG2 5U
102106
#define MKSSTAT_CAPACITY (1U << MKSSTAT_CAPACITY_LOG2)
103107

drivers/gpu/drm/vmwgfx/vmwgfx_kms.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,16 @@
2525
*
2626
**************************************************************************/
2727

28+
#include "vmwgfx_kms.h"
29+
#include "vmw_surface_cache.h"
30+
2831
#include <drm/drm_atomic.h>
2932
#include <drm/drm_atomic_helper.h>
3033
#include <drm/drm_damage_helper.h>
3134
#include <drm/drm_fourcc.h>
3235
#include <drm/drm_rect.h>
3336
#include <drm/drm_sysfs.h>
3437

35-
#include "vmwgfx_kms.h"
36-
3738
void vmw_du_cleanup(struct vmw_display_unit *du)
3839
{
3940
struct vmw_private *dev_priv = vmw_priv(du->primary.dev);
@@ -351,7 +352,6 @@ static void vmw_cursor_update_position(struct vmw_private *dev_priv,
351352
spin_unlock(&dev_priv->cursor_lock);
352353
}
353354

354-
355355
void vmw_kms_cursor_snoop(struct vmw_surface *srf,
356356
struct ttm_object_file *tfile,
357357
struct ttm_buffer_object *bo,
@@ -369,6 +369,9 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
369369
SVGA3dCmdSurfaceDMA dma;
370370
} *cmd;
371371
int i, ret;
372+
const struct SVGA3dSurfaceDesc *desc =
373+
vmw_surface_get_desc(VMW_CURSOR_SNOOP_FORMAT);
374+
const u32 image_pitch = VMW_CURSOR_SNOOP_WIDTH * desc->pitchBytesPerBlock;
372375

373376
cmd = container_of(header, struct vmw_dma_cmd, header);
374377

@@ -394,7 +397,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
394397
box->x != 0 || box->y != 0 || box->z != 0 ||
395398
box->srcx != 0 || box->srcy != 0 || box->srcz != 0 ||
396399
box->d != 1 || box_count != 1 ||
397-
box->w > 64 || box->h > 64) {
400+
box->w > VMW_CURSOR_SNOOP_WIDTH || box->h > VMW_CURSOR_SNOOP_HEIGHT) {
398401
/* TODO handle none page aligned offsets */
399402
/* TODO handle more dst & src != 0 */
400403
/* TODO handle more then one copy */
@@ -408,7 +411,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
408411
}
409412

410413
kmap_offset = cmd->dma.guest.ptr.offset >> PAGE_SHIFT;
411-
kmap_num = (64*64*4) >> PAGE_SHIFT;
414+
kmap_num = (VMW_CURSOR_SNOOP_HEIGHT*image_pitch) >> PAGE_SHIFT;
412415

413416
ret = ttm_bo_reserve(bo, true, false, NULL);
414417
if (unlikely(ret != 0)) {
@@ -422,14 +425,15 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
422425

423426
virtual = ttm_kmap_obj_virtual(&map, &dummy);
424427

425-
if (box->w == 64 && cmd->dma.guest.pitch == 64*4) {
426-
memcpy(srf->snooper.image, virtual, 64*64*4);
428+
if (box->w == VMW_CURSOR_SNOOP_WIDTH && cmd->dma.guest.pitch == image_pitch) {
429+
memcpy(srf->snooper.image, virtual,
430+
VMW_CURSOR_SNOOP_HEIGHT*image_pitch);
427431
} else {
428432
/* Image is unsigned pointer. */
429433
for (i = 0; i < box->h; i++)
430-
memcpy(srf->snooper.image + i * 64,
434+
memcpy(srf->snooper.image + i * image_pitch,
431435
virtual + i * cmd->dma.guest.pitch,
432-
box->w * 4);
436+
box->w * desc->pitchBytesPerBlock);
433437
}
434438

435439
srf->snooper.age++;
@@ -480,7 +484,8 @@ void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
480484
du->cursor_age = du->cursor_surface->snooper.age;
481485
vmw_send_define_cursor_cmd(dev_priv,
482486
du->cursor_surface->snooper.image,
483-
64, 64,
487+
VMW_CURSOR_SNOOP_WIDTH,
488+
VMW_CURSOR_SNOOP_HEIGHT,
484489
du->hotspot_x + du->core_hotspot_x,
485490
du->hotspot_y + du->core_hotspot_y);
486491
}
@@ -1806,7 +1811,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
18061811
if (IS_ERR(vfb)) {
18071812
ret = PTR_ERR(vfb);
18081813
goto err_out;
1809-
}
1814+
}
18101815

18111816
err_out:
18121817
/* vmw_user_lookup_handle takes one ref so does new_fb */
@@ -2326,7 +2331,7 @@ static int vmw_du_update_layout(struct vmw_private *dev_priv,
23262331
if (ret == -EDEADLK) {
23272332
drm_modeset_backoff(&ctx);
23282333
goto retry;
2329-
}
2334+
}
23302335
goto out_fini;
23312336
}
23322337
}

drivers/gpu/drm/vmwgfx/vmwgfx_surface.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -815,11 +815,15 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
815815
res->backup_size = cur_bo_offset;
816816
if (metadata->scanout &&
817817
metadata->num_sizes == 1 &&
818-
metadata->sizes[0].width == 64 &&
819-
metadata->sizes[0].height == 64 &&
820-
metadata->format == SVGA3D_A8R8G8B8) {
821-
822-
srf->snooper.image = kzalloc(64 * 64 * 4, GFP_KERNEL);
818+
metadata->sizes[0].width == VMW_CURSOR_SNOOP_WIDTH &&
819+
metadata->sizes[0].height == VMW_CURSOR_SNOOP_HEIGHT &&
820+
metadata->format == VMW_CURSOR_SNOOP_FORMAT) {
821+
const struct SVGA3dSurfaceDesc *desc =
822+
vmw_surface_get_desc(VMW_CURSOR_SNOOP_FORMAT);
823+
const u32 cursor_size_bytes = VMW_CURSOR_SNOOP_WIDTH *
824+
VMW_CURSOR_SNOOP_HEIGHT *
825+
desc->pitchBytesPerBlock;
826+
srf->snooper.image = kzalloc(cursor_size_bytes, GFP_KERNEL);
823827
if (!srf->snooper.image) {
824828
DRM_ERROR("Failed to allocate cursor_image\n");
825829
ret = -ENOMEM;

0 commit comments

Comments
 (0)