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 > >
