From: Berkant Koc <me@berkoc.com>
To: Zack Rusin <zack.rusin@broadcom.com>,
bcm-kernel-feedback-list@broadcom.com,
dri-devel@lists.freedesktop.org
Cc: security@kernel.org, Daniel Vetter <daniel@ffwll.ch>,
David Airlie <airlied@gmail.com>,
Thomas Zimmermann <tzimmermann@suse.de>,
stable@vger.kernel.org
Subject: [PATCH] drm/vmwgfx: validate execbuf header.size lower bound
Date: Sun, 17 May 2026 15:05:00 +0200 [thread overview]
Message-ID: <20260517-vmwgfx-uaf-patch@berkoc.com> (raw)
In-Reply-To: <2026051743-genre-cacti-bdf3@gregkh>
Commit 32b415a9dc2c ("drm/vmwgfx: Validate command header size against
SVGA_CMD_MAX_DATASIZE") added an upper bound on the user-supplied
SVGA3dCmdHeader.size field but no matching lower bound. When
header->size is smaller than sizeof(cmd->body), the size_t subtraction
in expressions like
maxnum = (header->size - sizeof(cmd->body)) / sizeof(*decl);
underflows. The subsequent bound check
if (cmd->body.numVertexDecls > maxnum) return -EINVAL;
is bypassed because maxnum is ~SIZE_MAX, and the loop walks
attacker-chosen entries past the command buffer.
In vmw_cmd_draw this leads to a 4-byte OOB-read per iteration via
vmw_cmd_res_check(&decl[i].array.surfaceId, ...); on a surface-handle
collision, vmw_resource_relocation_add records the OOB address as
rel->offset (29-bit bitfield), and vmw_resource_relocations_apply
later performs a 32-bit kernel write at cb + rel->offset.
The same root cause is present in vmw_cmd_dma (suffix pointer-arith
underflow leading to OOB-read of suffix->suffixSize) and
vmw_cmd_shader_define (size_t wraparound passed to
vmw_compat_shader_add).
Reachable via DRM_VMW_EXECBUF (DRM_RENDER_ALLOW). Reject undersized
headers at all three sites before the subtraction.
Cc: stable@vger.kernel.org # v6.18+
Fixes: 32b415a9dc2c ("drm/vmwgfx: Validate command header size against SVGA_CMD_MAX_DATASIZE")
Signed-off-by: Berkant Koc <me@berkoc.com>
---
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index e1f18020170a..6f9c7d61cc66 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -1506,6 +1506,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("DMA cmd header.size too small.\n");
+ return -EINVAL;
+ }
+
suffix = (SVGA3dCmdSurfaceDMASuffix *)((unsigned long) &cmd->body +
header->size - sizeof(*suffix));
@@ -1572,6 +1578,12 @@ static int vmw_cmd_draw(struct vmw_private *dev_priv,
return ret;
cmd = container_of(header, typeof(*cmd), header);
+
+ if (unlikely(header->size < sizeof(cmd->body))) {
+ VMW_DEBUG_USER("Draw cmd header.size smaller than body.\n");
+ return -EINVAL;
+ }
+
maxnum = (header->size - sizeof(cmd->body)) / sizeof(*decl);
if (unlikely(cmd->body.numVertexDecls > maxnum)) {
@@ -1915,6 +1927,11 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv,
if (unlikely(!dev_priv->has_mob))
return 0;
+ if (unlikely(cmd->header.size < sizeof(cmd->body))) {
+ VMW_DEBUG_USER("Shader define cmd header.size smaller than body.\n");
+ return -EINVAL;
+ }
+
size = cmd->header.size - sizeof(cmd->body);
ret = vmw_compat_shader_add(dev_priv, vmw_context_res_man(ctx),
cmd->body.shid, cmd + 1, cmd->body.type,
--
2.47.3
next prev parent reply other threads:[~2026-05-17 14:07 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-17 13:00 [REPORT] drm/vmwgfx: vmw_cmd_draw header.size lower-bound missing - guest-local OOB-read/write Berkant Koc
2026-05-17 13:37 ` Greg KH
2026-05-17 13:05 ` Berkant Koc [this message]
2026-05-17 23:23 ` [PATCH] drm/vmwgfx: validate execbuf header.size lower bound Zack Rusin
2026-05-18 0:56 ` Berkant Koc
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260517-vmwgfx-uaf-patch@berkoc.com \
--to=me@berkoc.com \
--cc=airlied@gmail.com \
--cc=bcm-kernel-feedback-list@broadcom.com \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=security@kernel.org \
--cc=stable@vger.kernel.org \
--cc=tzimmermann@suse.de \
--cc=zack.rusin@broadcom.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.