Skip to content

Commit d09e21b

Browse files
zackrsfX-bot
authored andcommitted
drm/vmwgfx: Fix shader stage validation
commit 14abdfae508228a7307f7491b5c4215ae70c6542 upstream. For multiple commands the driver was not correctly validating the shader stages resulting in possible kernel oopses. The validation code was only. if ever, checking the upper bound on the shader stages but never a lower bound (valid shader stages start at 1 not 0). Fixes kernel oopses ending up in vmw_binding_add, e.g.: Oops: 0000 [#1] PREEMPT SMP PTI CPU: 1 PID: 2443 Comm: testcase Not tainted 6.3.0-rc4-vmwgfx #1 Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020 RIP: 0010:vmw_binding_add+0x4c/0x140 [vmwgfx] Code: 7e 30 49 83 ff 0e 0f 87 ea 00 00 00 4b 8d 04 7f 89 d2 89 cb 48 c1 e0 03 4c 8b b0 40 3d 93 c0 48 8b 80 48 3d 93 c0 49 0f af de <48> 03 1c d0 4c 01 e3 49 8> RSP: 0018:ffffb8014416b968 EFLAGS: 00010206 RAX: ffffffffc0933ec0 RBX: 0000000000000000 RCX: 0000000000000000 RDX: 00000000ffffffff RSI: ffffb8014416b9c0 RDI: ffffb8014316f000 RBP: ffffb8014416b998 R08: 0000000000000003 R09: 746f6c735f726564 R10: ffffffffaaf2bda0 R11: 732e676e69646e69 R12: ffffb8014316f000 R13: ffffb8014416b9c0 R14: 0000000000000040 R15: 0000000000000006 FS: 00007fba8c0af740(0000) GS:ffff8a1277c80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000007c0933eb8 CR3: 0000000118244001 CR4: 00000000003706e0 Call Trace: <TASK> vmw_view_bindings_add+0xf5/0x1b0 [vmwgfx] ? ___drm_dbg+0x8a/0xb0 [drm] vmw_cmd_dx_set_shader_res+0x8f/0xc0 [vmwgfx] vmw_execbuf_process+0x590/0x1360 [vmwgfx] vmw_execbuf_ioctl+0x173/0x370 [vmwgfx] ? __drm_dev_dbg+0xb4/0xe0 [drm] ? __pfx_vmw_execbuf_ioctl+0x10/0x10 [vmwgfx] drm_ioctl_kernel+0xbc/0x160 [drm] drm_ioctl+0x2d2/0x580 [drm] ? __pfx_vmw_execbuf_ioctl+0x10/0x10 [vmwgfx] ? do_fault+0x1a6/0x420 vmw_generic_ioctl+0xbd/0x180 [vmwgfx] vmw_unlocked_ioctl+0x19/0x20 [vmwgfx] __x64_sys_ioctl+0x96/0xd0 do_syscall_64+0x5d/0x90 ? handle_mm_fault+0xe4/0x2f0 ? debug_smp_processor_id+0x1b/0x30 ? fpregs_assert_state_consistent+0x2e/0x50 ? exit_to_user_mode_prepare+0x40/0x180 ? irqentry_exit_to_user_mode+0xd/0x20 ? irqentry_exit+0x3f/0x50 ? exc_page_fault+0x8b/0x180 entry_SYSCALL_64_after_hwframe+0x72/0xdc Signed-off-by: Zack Rusin <[email protected]> Cc: [email protected] Reported-by: Ziming Zhang <[email protected]> Testcase-found-by: Niels De Graef <[email protected]> Fixes: d80efd5 ("drm/vmwgfx: Initial DX support") Cc: <[email protected]> # v4.3+ Reviewed-by: Maaz Mombasawala<[email protected]> Reviewed-by: Martin Krastev <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 799b1db commit d09e21b

File tree

2 files changed

+24
-18
lines changed

2 files changed

+24
-18
lines changed

drivers/gpu/drm/vmwgfx/vmwgfx_drv.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1606,4 +1606,17 @@ static inline void vmw_mmio_write(u32 value, u32 *addr)
16061606
{
16071607
WRITE_ONCE(*addr, value);
16081608
}
1609+
1610+
static inline bool vmw_shadertype_is_valid(enum vmw_sm_type shader_model,
1611+
u32 shader_type)
1612+
{
1613+
SVGA3dShaderType max_allowed = SVGA3D_SHADERTYPE_PREDX_MAX;
1614+
1615+
if (shader_model >= VMW_SM_5)
1616+
max_allowed = SVGA3D_SHADERTYPE_MAX;
1617+
else if (shader_model >= VMW_SM_4)
1618+
max_allowed = SVGA3D_SHADERTYPE_DX10_MAX;
1619+
return shader_type >= SVGA3D_SHADERTYPE_MIN && shader_type < max_allowed;
1620+
}
1621+
16091622
#endif

drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,7 +1998,7 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv,
19981998

19991999
cmd = container_of(header, typeof(*cmd), header);
20002000

2001-
if (cmd->body.type >= SVGA3D_SHADERTYPE_PREDX_MAX) {
2001+
if (!vmw_shadertype_is_valid(VMW_SM_LEGACY, cmd->body.type)) {
20022002
VMW_DEBUG_USER("Illegal shader type %u.\n",
20032003
(unsigned int) cmd->body.type);
20042004
return -EINVAL;
@@ -2120,8 +2120,6 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv,
21202120
SVGA3dCmdHeader *header)
21212121
{
21222122
VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetSingleConstantBuffer);
2123-
SVGA3dShaderType max_shader_num = has_sm5_context(dev_priv) ?
2124-
SVGA3D_NUM_SHADERTYPE : SVGA3D_NUM_SHADERTYPE_DX10;
21252123

21262124
struct vmw_resource *res = NULL;
21272125
struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
@@ -2138,6 +2136,14 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv,
21382136
if (unlikely(ret != 0))
21392137
return ret;
21402138

2139+
if (!vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type) ||
2140+
cmd->body.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) {
2141+
VMW_DEBUG_USER("Illegal const buffer shader %u slot %u.\n",
2142+
(unsigned int) cmd->body.type,
2143+
(unsigned int) cmd->body.slot);
2144+
return -EINVAL;
2145+
}
2146+
21412147
binding.bi.ctx = ctx_node->ctx;
21422148
binding.bi.res = res;
21432149
binding.bi.bt = vmw_ctx_binding_cb;
@@ -2146,14 +2152,6 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv,
21462152
binding.size = cmd->body.sizeInBytes;
21472153
binding.slot = cmd->body.slot;
21482154

2149-
if (binding.shader_slot >= max_shader_num ||
2150-
binding.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) {
2151-
VMW_DEBUG_USER("Illegal const buffer shader %u slot %u.\n",
2152-
(unsigned int) cmd->body.type,
2153-
(unsigned int) binding.slot);
2154-
return -EINVAL;
2155-
}
2156-
21572155
vmw_binding_add(ctx_node->staged, &binding.bi, binding.shader_slot,
21582156
binding.slot);
21592157

@@ -2174,15 +2172,13 @@ static int vmw_cmd_dx_set_shader_res(struct vmw_private *dev_priv,
21742172
{
21752173
VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShaderResources) =
21762174
container_of(header, typeof(*cmd), header);
2177-
SVGA3dShaderType max_allowed = has_sm5_context(dev_priv) ?
2178-
SVGA3D_SHADERTYPE_MAX : SVGA3D_SHADERTYPE_DX10_MAX;
21792175

21802176
u32 num_sr_view = (cmd->header.size - sizeof(cmd->body)) /
21812177
sizeof(SVGA3dShaderResourceViewId);
21822178

21832179
if ((u64) cmd->body.startView + (u64) num_sr_view >
21842180
(u64) SVGA3D_DX_MAX_SRVIEWS ||
2185-
cmd->body.type >= max_allowed) {
2181+
!vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type)) {
21862182
VMW_DEBUG_USER("Invalid shader binding.\n");
21872183
return -EINVAL;
21882184
}
@@ -2206,8 +2202,6 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv,
22062202
SVGA3dCmdHeader *header)
22072203
{
22082204
VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShader);
2209-
SVGA3dShaderType max_allowed = has_sm5_context(dev_priv) ?
2210-
SVGA3D_SHADERTYPE_MAX : SVGA3D_SHADERTYPE_DX10_MAX;
22112205
struct vmw_resource *res = NULL;
22122206
struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
22132207
struct vmw_ctx_bindinfo_shader binding;
@@ -2218,8 +2212,7 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv,
22182212

22192213
cmd = container_of(header, typeof(*cmd), header);
22202214

2221-
if (cmd->body.type >= max_allowed ||
2222-
cmd->body.type < SVGA3D_SHADERTYPE_MIN) {
2215+
if (!vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type)) {
22232216
VMW_DEBUG_USER("Illegal shader type %u.\n",
22242217
(unsigned int) cmd->body.type);
22252218
return -EINVAL;

0 commit comments

Comments
 (0)