From a5b4dedaddbf612daf3eaf263bb4bbc8bf447e79 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Wed, 31 May 2017 11:07:03 +0200 Subject: [PATCH] wined3d: Validate parameter lengths in shader_sm4_read_dst_param() (AFL). Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/shader_sm4.c | 48 +++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/dlls/wined3d/shader_sm4.c b/dlls/wined3d/shader_sm4.c index a9fedbc44f4..a1b30e52ed9 100644 --- a/dlls/wined3d/shader_sm4.c +++ b/dlls/wined3d/shader_sm4.c @@ -510,7 +510,7 @@ static const enum wined3d_data_type data_type_table[] = static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr, enum wined3d_data_type data_type, struct wined3d_shader_src_param *src_param); -static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD **ptr, +static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end, enum wined3d_data_type data_type, struct wined3d_shader_dst_param *dst_param); static void shader_sm4_read_conditional_op(struct wined3d_shader_instruction *ins, @@ -571,7 +571,7 @@ static void shader_sm4_read_dcl_resource(struct wined3d_shader_instruction *ins, ins->declaration.semantic.resource_type = resource_type_table[resource_type]; } reg_data_type = opcode == WINED3D_SM4_OP_DCL_RESOURCE ? WINED3D_DATA_RESOURCE : WINED3D_DATA_UAV; - shader_sm4_read_dst_param(priv, &tokens, reg_data_type, &ins->declaration.semantic.reg); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], reg_data_type, &ins->declaration.semantic.reg); components = *tokens++; if ((components & 0xfff0) != (components & 0xf) * 0x1110) @@ -608,14 +608,15 @@ static void shader_sm4_read_dcl_sampler(struct wined3d_shader_instruction *ins, ins->flags = (opcode_token & WINED3D_SM4_SAMPLER_MODE_MASK) >> WINED3D_SM4_SAMPLER_MODE_SHIFT; if (ins->flags & ~WINED3D_SM4_SAMPLER_COMPARISON) FIXME("Unhandled sampler mode %#x.\n", ins->flags); - shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_SAMPLER, &ins->declaration.dst); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_SAMPLER, &ins->declaration.dst); } static void shader_sm4_read_dcl_index_range(struct wined3d_shader_instruction *ins, DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, struct wined3d_sm4_data *priv) { - shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_OPAQUE, &ins->declaration.index_range.first_register); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_OPAQUE, + &ins->declaration.index_range.first_register); ins->declaration.index_range.last_register = *tokens; } @@ -671,14 +672,15 @@ static void shader_sm4_read_declaration_dst(struct wined3d_shader_instruction *i DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, struct wined3d_sm4_data *priv) { - shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.dst); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.dst); } static void shader_sm4_read_declaration_register_semantic(struct wined3d_shader_instruction *ins, DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, struct wined3d_sm4_data *priv) { - shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.register_semantic.reg); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, + &ins->declaration.register_semantic.reg); ins->declaration.register_semantic.sysval_semantic = *tokens; } @@ -687,7 +689,7 @@ static void shader_sm4_read_dcl_input_ps(struct wined3d_shader_instruction *ins, struct wined3d_sm4_data *priv) { ins->flags = (opcode_token & WINED3D_SM4_INTERPOLATION_MODE_MASK) >> WINED3D_SM4_INTERPOLATION_MODE_SHIFT; - shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.dst); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.dst); } static void shader_sm4_read_dcl_input_ps_siv(struct wined3d_shader_instruction *ins, @@ -695,7 +697,8 @@ static void shader_sm4_read_dcl_input_ps_siv(struct wined3d_shader_instruction * struct wined3d_sm4_data *priv) { ins->flags = (opcode_token & WINED3D_SM4_INTERPOLATION_MODE_MASK) >> WINED3D_SM4_INTERPOLATION_MODE_SHIFT; - shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.register_semantic.reg); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, + &ins->declaration.register_semantic.reg); ins->declaration.register_semantic.sysval_semantic = *tokens; } @@ -801,7 +804,7 @@ static void shader_sm5_read_dcl_uav_raw(struct wined3d_shader_instruction *ins, DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, struct wined3d_sm4_data *priv) { - shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_UAV, &ins->declaration.dst); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UAV, &ins->declaration.dst); ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT; } @@ -809,7 +812,8 @@ static void shader_sm5_read_dcl_uav_structured(struct wined3d_shader_instruction DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, struct wined3d_sm4_data *priv) { - shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_UAV, &ins->declaration.structured_resource.reg); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UAV, + &ins->declaration.structured_resource.reg); ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT; ins->declaration.structured_resource.byte_stride = *tokens; if (ins->declaration.structured_resource.byte_stride % 4) @@ -820,7 +824,7 @@ static void shader_sm5_read_dcl_tgsm_raw(struct wined3d_shader_instruction *ins, DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, struct wined3d_sm4_data *priv) { - shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.tgsm_raw.reg); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.tgsm_raw.reg); ins->declaration.tgsm_raw.byte_count = *tokens; if (ins->declaration.tgsm_raw.byte_count % 4) FIXME("Byte count %u is not multiple of 4.\n", ins->declaration.tgsm_raw.byte_count); @@ -830,7 +834,8 @@ static void shader_sm5_read_dcl_tgsm_structured(struct wined3d_shader_instructio DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, struct wined3d_sm4_data *priv) { - shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_FLOAT, &ins->declaration.tgsm_structured.reg); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, + &ins->declaration.tgsm_structured.reg); ins->declaration.tgsm_structured.byte_stride = *tokens++; ins->declaration.tgsm_structured.structure_count = *tokens; if (ins->declaration.tgsm_structured.byte_stride % 4) @@ -841,7 +846,8 @@ static void shader_sm5_read_dcl_resource_structured(struct wined3d_shader_instru DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, struct wined3d_sm4_data *priv) { - shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_RESOURCE, &ins->declaration.structured_resource.reg); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_RESOURCE, + &ins->declaration.structured_resource.reg); ins->declaration.structured_resource.byte_stride = *tokens; if (ins->declaration.structured_resource.byte_stride % 4) FIXME("Byte stride %u is not multiple of 4.\n", ins->declaration.structured_resource.byte_stride); @@ -851,7 +857,7 @@ static void shader_sm5_read_dcl_resource_raw(struct wined3d_shader_instruction * DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count, struct wined3d_sm4_data *priv) { - shader_sm4_read_dst_param(priv, &tokens, WINED3D_DATA_RESOURCE, &ins->declaration.dst); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_RESOURCE, &ins->declaration.dst); } static void shader_sm5_read_sync(struct wined3d_shader_instruction *ins, @@ -1512,11 +1518,18 @@ static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD return TRUE; } -static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD **ptr, +static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end, enum wined3d_data_type data_type, struct wined3d_shader_dst_param *dst_param) { enum wined3d_shader_src_modifier modifier; - DWORD token = **ptr; + DWORD token; + + if (*ptr >= end) + { + WARN("Invalid ptr %p >= end %p.\n", *ptr, end); + return FALSE; + } + token = **ptr; if (!shader_sm4_read_param(priv, ptr, data_type, &dst_param->reg, &modifier)) { @@ -1659,7 +1672,8 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi for (i = 0; i < ins->dst_count; ++i) { - if (!(shader_sm4_read_dst_param(priv, &p, map_data_type(opcode_info->dst_info[i]), &priv->dst_param[i]))) + if (!(shader_sm4_read_dst_param(priv, &p, *ptr, map_data_type(opcode_info->dst_info[i]), + &priv->dst_param[i]))) { ins->handler_idx = WINED3DSIH_TABLE_SIZE; return;