Hi Zack,

Gentle ping on this one -- vmw_cmd_dma() still dereferences the suffix
without checking that header->size is large enough to contain it.
A DRM_AUTH client can reach this from execbuf.

Any feedback?

Thanks,
Aldo

On Sun, Aug 09, 2026 10:25 AM, Aldo Ariel Panzardo <[email protected]>
wrote:

> vmw_cmd_dma() locates the SVGA3dCmdSurfaceDMASuffix at the end of the
> command and dereferences it:
>
>         suffix = (SVGA3dCmdSurfaceDMASuffix *)((unsigned long) &cmd->body +
>                                                header->size -
> sizeof(*suffix));
>         if (unlikely(suffix->suffixSize != sizeof(*suffix))) {
>
> header->size comes straight from userspace through DRM_IOCTL_VMW_EXECBUF
> (DRM_RENDER_ALLOW) and is only bounded from above: vmw_cmd_check()
> rejects header->size > SVGA_CMD_MAX_DATASIZE and commands that do not fit
> the buffer, and struct vmw_cmd_entry carries no per-command minimum size.
> There is no lower bound. When header->size is smaller than sizeof(*suffix)
> the pointer arithmetic underflows and the read of suffix->suffixSize is an
> out-of-bounds read ahead of the command; when it is smaller than the body
> plus the suffix, the body accesses that follow are out of bounds as well.
>
> Reject the command before computing the suffix pointer when header->size
> cannot hold both the fixed body and the trailing suffix.
>
> Found by a syzkaller instance fuzzing the vmwgfx command stream:
>
>   BUG: KASAN: vmalloc-out-of-bounds in vmw_cmd_dma+0x508/0x5b0
>   Read of size 4 ...
>    vmw_cmd_dma+0x508/0x5b0 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
>    vmw_execbuf_process+0xd06/0x35f0
>    vmw_execbuf_ioctl+0x1cc/0x5a0
>
> Fixes: cbd75e97a525 ("drm/vmwgfx: Make sure user-space can't DMA across
> buffer object boundaries v2")
> Cc: [email protected]
> Signed-off-by: Aldo Ariel Panzardo <[email protected]>
> ---
>  drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> index 6b921db2dcd2..02eb383f91b5 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
> @@ -1524,6 +1524,12 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv,
>         bool dirty;
>
>         cmd = container_of(header, typeof(*cmd), header);
> +
> +       if (unlikely(header->size < sizeof(cmd->body) + sizeof(*suffix))) {
> +               VMW_DEBUG_USER("Invalid SURFACE_DMA command size.\n");
> +               return -EINVAL;
> +       }
> +
>         suffix = (SVGA3dCmdSurfaceDMASuffix *)((unsigned long) &cmd->body +
>                                                header->size -
> sizeof(*suffix));
>
> --
> 2.43.0
>
>

Reply via email to