On 8/9/26 1:45 PM, Zack Rusin wrote:
> Validate the pitch, alongside the box dimensions before trying
> to copy data from the underlying surface. Fixes possible
> out of bounds reads with cursor snooping.
> 
> Fixes: 2ac863719e51 ("vmwgfx: Snoop DMA transfers with non-covering sizes")
> Cc: [email protected]
> Reported-by: Youness HFA <[email protected]>
> Signed-off-by: Zack Rusin <[email protected]>
> ---
>  drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c | 20 +++++++++++++++++---
>  1 file changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c 
> b/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c
> index d1e7df500190..f4d14b00d7aa 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c
> @@ -324,6 +324,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
>       unsigned long kmap_num;
>       SVGA3dCopyBox *box;
>       u32 box_count;
> +     u64 src_extent;
>       void *virtual;
>       bool is_iomem;
>       struct vmw_dma_cmd {
> @@ -372,8 +373,19 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
>               return;
>       }
>  
> +     if (box->w == 0 || box->h == 0)
> +             return;
> +
> +     src_extent = (u64)(box->h - 1) * cmd->dma.guest.pitch +
> +                  (u64)box->w * desc->pitchBytesPerBlock;
> +     if (src_extent > bo->base.size) {
> +             DRM_ERROR("Cursor snoop source of %llu bytes exceeds the %zu 
> byte buffer\n",
> +                       src_extent, bo->base.size);
> +             return;
> +     }
> +
>       kmap_offset = cmd->dma.guest.ptr.offset >> PAGE_SHIFT;
> -     kmap_num = (VMW_CURSOR_SNOOP_HEIGHT * image_pitch) >> PAGE_SHIFT;
> +     kmap_num = PFN_UP(src_extent);
>  
>       ret = ttm_bo_reserve(bo, true, false, NULL);
>       if (unlikely(ret != 0)) {
> @@ -387,14 +399,16 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
>  
>       virtual = ttm_kmap_obj_virtual(&map, &is_iomem);
>  
> -     if (box->w == VMW_CURSOR_SNOOP_WIDTH && cmd->dma.guest.pitch == 
> image_pitch) {
> +     if (box->w == VMW_CURSOR_SNOOP_WIDTH &&
> +         box->h == VMW_CURSOR_SNOOP_HEIGHT &&
> +         cmd->dma.guest.pitch == image_pitch) {
>               memcpy(srf->snooper.image, virtual,
>                      VMW_CURSOR_SNOOP_HEIGHT * image_pitch);
>       } else {
>               /* Image is unsigned pointer. */
>               for (i = 0; i < box->h; i++)
>                       memcpy(srf->snooper.image + i * image_pitch,
> -                            virtual + i * cmd->dma.guest.pitch,
> +                            virtual + (size_t)i * cmd->dma.guest.pitch,
>                              box->w * desc->pitchBytesPerBlock);
>       }
>       srf->snooper.id++;


LGTM!

Reviewed-by: Maaz Mombasawala <[email protected]>

Will you also backport this to pre-6.14 LTR kernels when all this code was in 
vmwgfx_kms.c?


-- 
Maaz Mombasawala <[email protected]>

Reply via email to