wined3d: Validate parameter lengths in shader_sm4_read_dst_param() (AFL).

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Henri Verbeet 2017-05-31 11:07:03 +02:00 committed by Alexandre Julliard
parent 3821dcf996
commit a5b4dedadd
1 changed files with 31 additions and 17 deletions

View File

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