vmw_cmd_check verifies that a command's declared size fits in the submitted buffer, but handlers can access fields beyond the declared body. A truncated body can therefore cause relocations to target the next command. Applying those relocations after validation can change an already validated command ID and bypass command restrictions. Legacy query conversion can also overwrite the next command, while texture-state parsing can access fields beyond a truncated final record. Check each handler's minimum body size before accessing command fields. Use the common prefix for shared handlers to preserve shorter command variants, and reject texture-state arrays containing incomplete records. Fixes: fb1d9738ca05 ("drm/vmwgfx: Add DRM driver for VMware Virtual GPU") Cc: stable@vger.kernel.org Signed-off-by: Zack Rusin --- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 200 ++++++++++++++++++++++++ 1 file changed, 200 insertions(+) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index a9136a6523cb..7b943e99061e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -564,6 +564,29 @@ static int vmw_cmd_ok(struct vmw_private *dev_priv, return 0; } +/** + * vmw_cmd_body_fits - Check that a command body covers what a handler reads + * + * @header: Pointer to the command header in the command stream. + * @size: Number of body bytes that the command handler interprets. + * + * vmw_cmd_check() only verifies that @header->size fits into the submitted + * command buffer. A handler that reads past the declared body reads the next + * command, which is verified separately. A relocation recorded there would + * rewrite the already verified command after verification has finished. + * + * Return: true if the body is at least @size bytes, false otherwise. + */ +static bool vmw_cmd_body_fits(const SVGA3dCmdHeader *header, size_t size) +{ + if (likely(header->size >= size)) + return true; + + VMW_DEBUG_USER("SVGA3D command %u: body size %u is smaller than %zu.\n", + header->id, header->size, size); + return false; +} + /** * vmw_resources_reserve - Reserve all resources on the sw_context's resource * list. @@ -810,6 +833,9 @@ static int vmw_cmd_cid_check(struct vmw_private *dev_priv, VMW_DECLARE_CMD_VAR(*cmd, uint32_t) = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, VMW_RES_DIRTY_SET, user_context_converter, &cmd->body, NULL); @@ -853,6 +879,8 @@ static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv, int ret; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; if (cmd->body.type >= SVGA3D_RT_MAX) { VMW_DEBUG_USER("Illegal render target type %u.\n", @@ -898,6 +926,8 @@ static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv, int ret; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, @@ -918,6 +948,9 @@ static int vmw_cmd_buffer_copy_check(struct vmw_private *dev_priv, int ret; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.src, NULL); @@ -937,6 +970,9 @@ static int vmw_cmd_pred_copy_check(struct vmw_private *dev_priv, int ret; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.srcSid, NULL); @@ -956,6 +992,9 @@ static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv, int ret; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.src.sid, NULL); @@ -974,6 +1013,9 @@ static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv, VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBlitSurfaceToScreen) = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.srcImage.sid, NULL); @@ -986,6 +1028,9 @@ static int vmw_cmd_present_check(struct vmw_private *dev_priv, VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdPresent) = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.sid, NULL); @@ -1243,6 +1288,8 @@ static int vmw_cmd_dx_define_query(struct vmw_private *dev_priv, return -EINVAL; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; if (cmd->body.type < SVGA3D_QUERYTYPE_MIN || cmd->body.type >= SVGA3D_QUERYTYPE_MAX) @@ -1280,6 +1327,8 @@ static int vmw_cmd_dx_bind_query(struct vmw_private *dev_priv, return -EINVAL; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; /* * Look up the buffer pointed to by q.mobid, put it on the relocation @@ -1310,6 +1359,9 @@ static int vmw_cmd_begin_gb_query(struct vmw_private *dev_priv, VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBeginGBQuery) = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, VMW_RES_DIRTY_SET, user_context_converter, &cmd->body.cid, NULL); @@ -1329,6 +1381,9 @@ static int vmw_cmd_begin_query(struct vmw_private *dev_priv, VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBeginQuery) = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (unlikely(dev_priv->has_mob)) { VMW_DECLARE_CMD_VAR(gb_cmd, SVGA3dCmdBeginGBQuery); @@ -1364,6 +1419,9 @@ static int vmw_cmd_end_gb_query(struct vmw_private *dev_priv, int ret; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + ret = vmw_cmd_cid_check(dev_priv, sw_context, header); if (unlikely(ret != 0)) return ret; @@ -1394,6 +1452,9 @@ static int vmw_cmd_end_query(struct vmw_private *dev_priv, int ret; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (dev_priv->has_mob) { VMW_DECLARE_CMD_VAR(gb_cmd, SVGA3dCmdEndGBQuery); @@ -1440,6 +1501,9 @@ static int vmw_cmd_wait_gb_query(struct vmw_private *dev_priv, int ret; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + ret = vmw_cmd_cid_check(dev_priv, sw_context, header); if (unlikely(ret != 0)) return ret; @@ -1468,6 +1532,9 @@ static int vmw_cmd_wait_query(struct vmw_private *dev_priv, int ret; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (dev_priv->has_mob) { VMW_DECLARE_CMD_VAR(gb_cmd, SVGA3dCmdWaitForGBQuery); @@ -1637,6 +1704,15 @@ static int vmw_cmd_tex_state(struct vmw_private *dev_priv, int ret; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + + /* The loop below must not read a truncated trailing state. */ + if ((header->size - sizeof(cmd->body)) % sizeof(*cur_state)) { + VMW_DEBUG_USER("Invalid texture state size %u.\n", + header->size); + return -EINVAL; + } ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, VMW_RES_DIRTY_SET, user_context_converter, @@ -1782,6 +1858,9 @@ static int vmw_cmd_bind_gb_surface(struct vmw_private *dev_priv, VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBindGBSurface) = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + return vmw_cmd_switch_backup(dev_priv, sw_context, vmw_res_surface, user_surface_converter, &cmd->body.sid, &cmd->body.mobid, 0); @@ -1801,6 +1880,9 @@ static int vmw_cmd_update_gb_image(struct vmw_private *dev_priv, VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdUpdateGBImage) = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.image.sid, NULL); @@ -1820,6 +1902,9 @@ static int vmw_cmd_update_gb_surface(struct vmw_private *dev_priv, VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdUpdateGBSurface) = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_CLEAR, user_surface_converter, &cmd->body.sid, NULL); @@ -1839,6 +1924,9 @@ static int vmw_cmd_readback_gb_image(struct vmw_private *dev_priv, VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdReadbackGBImage) = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.image.sid, NULL); @@ -1859,6 +1947,9 @@ static int vmw_cmd_readback_gb_surface(struct vmw_private *dev_priv, VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdReadbackGBSurface) = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_CLEAR, user_surface_converter, &cmd->body.sid, NULL); @@ -1879,6 +1970,9 @@ static int vmw_cmd_invalidate_gb_image(struct vmw_private *dev_priv, VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdInvalidateGBImage) = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.image.sid, NULL); @@ -1899,6 +1993,9 @@ static int vmw_cmd_invalidate_gb_surface(struct vmw_private *dev_priv, VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdInvalidateGBSurface) = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_CLEAR, user_surface_converter, &cmd->body.sid, NULL); @@ -1921,6 +2018,8 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv, struct vmw_resource *ctx; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, VMW_RES_DIRTY_SET, user_context_converter, @@ -1960,6 +2059,8 @@ static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv, struct vmw_resource *ctx; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, VMW_RES_DIRTY_SET, user_context_converter, @@ -1999,6 +2100,8 @@ static int vmw_cmd_set_shader(struct vmw_private *dev_priv, int ret; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; if (!vmw_shadertype_is_valid(VMW_SM_LEGACY, cmd->body.type)) { VMW_DEBUG_USER("Illegal shader type %u.\n", @@ -2077,6 +2180,8 @@ static int vmw_cmd_set_shader_const(struct vmw_private *dev_priv, int ret; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, VMW_RES_DIRTY_SET, user_context_converter, @@ -2104,6 +2209,9 @@ static int vmw_cmd_bind_gb_shader(struct vmw_private *dev_priv, VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBindGBShader) = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + return vmw_cmd_switch_backup(dev_priv, sw_context, vmw_res_shader, user_shader_converter, &cmd->body.shid, &cmd->body.mobid, cmd->body.offsetInBytes); @@ -2133,6 +2241,9 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, return -EINVAL; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.sid, &res); @@ -2186,6 +2297,9 @@ vmw_cmd_dx_set_constant_buffer_offset(struct vmw_private *dev_priv, return -EINVAL; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (cmd->body.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) { VMW_DEBUG_USER("Illegal const buffer slot %u.\n", (unsigned int) cmd->body.slot); @@ -2217,6 +2331,9 @@ static int vmw_cmd_dx_set_shader_res(struct vmw_private *dev_priv, u32 num_sr_view = (cmd->header.size - sizeof(cmd->body)) / sizeof(SVGA3dShaderResourceViewId); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if ((u64) cmd->body.startView + (u64) num_sr_view > (u64) SVGA3D_DX_MAX_SRVIEWS || !vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type)) { @@ -2252,6 +2369,8 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, return -EINVAL; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; if (!vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type)) { VMW_DEBUG_USER("Illegal shader type %u.\n", @@ -2309,6 +2428,9 @@ static int vmw_cmd_dx_set_vertex_buffers(struct vmw_private *dev_priv, return -EINVAL; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + num = (cmd->header.size - sizeof(cmd->body)) / sizeof(SVGA3dVertexBuffer); if ((u64)num + (u64)cmd->body.startBuffer > @@ -2360,6 +2482,9 @@ static int vmw_cmd_dx_set_index_buffer(struct vmw_private *dev_priv, return -EINVAL; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.sid, &res); @@ -2395,6 +2520,9 @@ static int vmw_cmd_dx_set_rendertargets(struct vmw_private *dev_priv, sizeof(SVGA3dRenderTargetViewId); int ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (num_rt_view > SVGA3D_DX_MAX_RENDER_TARGETS) { VMW_DEBUG_USER("Invalid DX Rendertarget binding.\n"); return -EINVAL; @@ -2426,6 +2554,9 @@ static int vmw_cmd_dx_clear_rendertarget_view(struct vmw_private *dev_priv, container_of(header, typeof(*cmd), header); struct vmw_resource *ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + ret = vmw_view_id_val_add(sw_context, vmw_view_rt, cmd->body.renderTargetViewId); @@ -2448,6 +2579,9 @@ static int vmw_cmd_dx_clear_depthstencil_view(struct vmw_private *dev_priv, container_of(header, typeof(*cmd), header); struct vmw_resource *ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + ret = vmw_view_id_val_add(sw_context, vmw_view_ds, cmd->body.depthStencilViewId); @@ -2481,6 +2615,9 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv, return -EINVAL; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(*cmd) - sizeof(*header))) + return -EINVAL; + if (unlikely(cmd->sid == SVGA3D_INVALID_ID)) { VMW_DEBUG_USER("Invalid surface id.\n"); return -EINVAL; @@ -2529,6 +2666,9 @@ static int vmw_cmd_dx_set_so_targets(struct vmw_private *dev_priv, return -EINVAL; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + num = (cmd->header.size - sizeof(cmd->body)) / sizeof(SVGA3dSoTarget); if (num > SVGA3D_DX_MAX_SOTARGETS) { @@ -2582,6 +2722,9 @@ static int vmw_cmd_dx_so_define(struct vmw_private *dev_priv, if (IS_ERR_OR_NULL(res)) return res ? PTR_ERR(res) : -EINVAL; cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(*cmd) - sizeof(*header))) + return -EINVAL; + ret = vmw_cotable_notify(res, cmd->defined_id); return ret; @@ -2617,6 +2760,9 @@ static int vmw_cmd_dx_check_subresource(struct vmw_private *dev_priv, offsetof(typeof(*cmd), sid)); cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->sid))) + return -EINVAL; + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->sid, NULL); @@ -2658,6 +2804,9 @@ static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv, struct vmw_resource *view; int ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!ctx_node) return -EINVAL; @@ -2695,6 +2844,9 @@ static int vmw_cmd_dx_define_shader(struct vmw_private *dev_priv, container_of(header, typeof(*cmd), header); int ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!ctx_node) return -EINVAL; @@ -2726,6 +2878,9 @@ static int vmw_cmd_dx_destroy_shader(struct vmw_private *dev_priv, container_of(header, typeof(*cmd), header); int ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!ctx_node) return -EINVAL; @@ -2752,6 +2907,9 @@ static int vmw_cmd_dx_bind_shader(struct vmw_private *dev_priv, container_of(header, typeof(*cmd), header); int ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (cmd->body.cid != SVGA3D_INVALID_ID) { ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context, VMW_RES_DIRTY_SET, @@ -2803,6 +2961,9 @@ static int vmw_cmd_dx_genmips(struct vmw_private *dev_priv, struct vmw_resource *view; struct vmw_res_cache_entry *rcache; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + view = vmw_view_id_val_add(sw_context, vmw_view_sr, cmd->body.shaderResourceViewId); if (IS_ERR(view)) @@ -2836,6 +2997,9 @@ static int vmw_cmd_dx_transfer_from_buffer(struct vmw_private *dev_priv, container_of(header, typeof(*cmd), header); int ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, VMW_RES_DIRTY_NONE, user_surface_converter, &cmd->body.srcSid, NULL); @@ -2861,6 +3025,9 @@ static int vmw_cmd_intra_surface_copy(struct vmw_private *dev_priv, VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdIntraSurfaceCopy) = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!(dev_priv->capabilities2 & SVGA_CAP2_INTRA_SURFACE_COPY)) return -EINVAL; @@ -2909,6 +3076,9 @@ static int vmw_cmd_clear_uav_uint(struct vmw_private *dev_priv, } *cmd = container_of(header, typeof(*cmd), header); struct vmw_resource *ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!has_sm5_context(dev_priv)) return -EINVAL; @@ -2928,6 +3098,9 @@ static int vmw_cmd_clear_uav_float(struct vmw_private *dev_priv, } *cmd = container_of(header, typeof(*cmd), header); struct vmw_resource *ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!has_sm5_context(dev_priv)) return -EINVAL; @@ -2949,6 +3122,9 @@ static int vmw_cmd_set_uav(struct vmw_private *dev_priv, sizeof(SVGA3dUAViewId); int ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!has_sm5_context(dev_priv)) return -EINVAL; @@ -2981,6 +3157,9 @@ static int vmw_cmd_set_cs_uav(struct vmw_private *dev_priv, sizeof(SVGA3dUAViewId); int ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!has_sm5_context(dev_priv)) return -EINVAL; @@ -3013,6 +3192,9 @@ static int vmw_cmd_dx_define_streamoutput(struct vmw_private *dev_priv, } *cmd = container_of(header, typeof(*cmd), header); int ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!has_sm5_context(dev_priv)) return -EINVAL; @@ -3044,6 +3226,9 @@ static int vmw_cmd_dx_destroy_streamoutput(struct vmw_private *dev_priv, SVGA3dCmdDXDestroyStreamOutput body; } *cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!ctx_node) { DRM_ERROR("DX Context not set.\n"); return -EINVAL; @@ -3081,6 +3266,9 @@ static int vmw_cmd_dx_bind_streamoutput(struct vmw_private *dev_priv, } *cmd = container_of(header, typeof(*cmd), header); int ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!has_sm5_context(dev_priv)) return -EINVAL; @@ -3123,6 +3311,9 @@ static int vmw_cmd_dx_set_streamoutput(struct vmw_private *dev_priv, } *cmd = container_of(header, typeof(*cmd), header); int ret; + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!ctx_node) { DRM_ERROR("DX Context not set.\n"); return -EINVAL; @@ -3175,6 +3366,9 @@ static int vmw_cmd_indexed_instanced_indirect(struct vmw_private *dev_priv, SVGA3dCmdDXDrawIndexedInstancedIndirect body; } *cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!has_sm5_context(dev_priv)) return -EINVAL; @@ -3192,6 +3386,9 @@ static int vmw_cmd_instanced_indirect(struct vmw_private *dev_priv, SVGA3dCmdDXDrawInstancedIndirect body; } *cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!has_sm5_context(dev_priv)) return -EINVAL; @@ -3209,6 +3406,9 @@ static int vmw_cmd_dispatch_indirect(struct vmw_private *dev_priv, SVGA3dCmdDXDispatchIndirect body; } *cmd = container_of(header, typeof(*cmd), header); + if (!vmw_cmd_body_fits(header, sizeof(cmd->body))) + return -EINVAL; + if (!has_sm5_context(dev_priv)) return -EINVAL; -- 2.53.0