Module: wine Branch: master Commit: 2594f58eb0e8db888ff4c341989583e98aaf3e99 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2594f58eb0e8db888ff4c34198...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Wed May 25 20:04:03 2016 +0200
d3d10: Validate offsets in parse_fx10_object() (AFL).
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/d3d10/effect.c | 87 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 22 deletions(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c index 2085d93..378f23f 100644 --- a/dlls/d3d10/effect.c +++ b/dlls/d3d10/effect.c @@ -244,7 +244,7 @@ static const struct d3d10_effect_state_storage_info d3d10_effect_state_storage_i {D3D10_SVT_SAMPLER, sizeof(default_sampler_desc), &default_sampler_desc }, };
-static BOOL fx10_copy_string(const char *data, size_t data_size, DWORD offset, char **s) +static BOOL fx10_get_string(const char *data, size_t data_size, DWORD offset, const char **s, size_t *l) { size_t len, max_len;
@@ -258,20 +258,40 @@ static BOOL fx10_copy_string(const char *data, size_t data_size, DWORD offset, c if (!(len = strnlen(data + offset, max_len))) { *s = NULL; + *l = 0; return TRUE; }
if (len == max_len) return FALSE;
- ++len; + *s = data + offset; + *l = ++len; + + return TRUE; +} + +static BOOL fx10_copy_string(const char *data, size_t data_size, DWORD offset, char **s) +{ + const char *p; + size_t len; + + if (!fx10_get_string(data, data_size, offset, &p, &len)) + return FALSE; + + if (!p) + { + *s = NULL; + return TRUE; + } + if (!(*s = HeapAlloc(GetProcessHeap(), 0, len))) { ERR("Failed to allocate string memory.\n"); return FALSE; }
- memcpy(*s, data + offset, len); + memcpy(*s, p, len);
return TRUE; } @@ -302,21 +322,13 @@ static BOOL copy_name(const char *ptr, char **name)
static const char *shader_get_string(const char *data, size_t data_size, DWORD offset) { - size_t len, max_len; - - if (offset >= data_size) - { - WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size); - return NULL; - } - - max_len = data_size - offset; - len = strnlen(data + offset, max_len); + const char *s; + size_t l;
- if (len == max_len) + if (!fx10_get_string(data, data_size, offset, &s, &l)) return NULL;
- return data + offset; + return l ? s : ""; }
static HRESULT shader_parse_signature(const char *data, DWORD data_size, struct d3d10_effect_shader_signature *s) @@ -1268,7 +1280,8 @@ static BOOL parse_fx10_state_group(const char **ptr, const char *data, return TRUE; }
-static HRESULT parse_fx10_object(struct d3d10_effect_object *o, const char **ptr, const char *data) +static HRESULT parse_fx10_object(const char *data, size_t data_size, + const char **ptr, struct d3d10_effect_object *o) { ID3D10EffectVariable *variable = &null_variable.ID3D10EffectVariable_iface; const char *data_ptr = NULL; @@ -1278,6 +1291,14 @@ static HRESULT parse_fx10_object(struct d3d10_effect_object *o, const char **ptr struct d3d10_effect *effect = o->pass->technique->effect; ID3D10Effect *e = &effect->ID3D10Effect_iface; DWORD tmp, variable_idx = 0; + const char *name; + size_t name_len; + + if (!require_space(*ptr - data, 4, sizeof(DWORD), data_size)) + { + WARN("Invalid offset %#lx (data size %#lx).\n", (long)(*ptr - data), (long)data_size); + return E_FAIL; + }
read_dword(ptr, &o->type); TRACE("Effect object is of type %#x.\n", o->type); @@ -1345,19 +1366,36 @@ static HRESULT parse_fx10_object(struct d3d10_effect_object *o, const char **ptr
case D3D10_EOO_PARSED_OBJECT: /* This is a local object, we've parsed in parse_fx10_local_object. */ - TRACE("Variable name %s.\n", debugstr_a(data + offset)); + if (!fx10_get_string(data, data_size, offset, &name, &name_len)) + { + WARN("Failed to get variable name.\n"); + return E_FAIL; + } + TRACE("Variable name %s.\n", debugstr_a(name));
- variable = e->lpVtbl->GetVariableByName(e, data + offset); + variable = e->lpVtbl->GetVariableByName(e, name); break;
case D3D10_EOO_PARSED_OBJECT_INDEX: /* This is a local object, we've parsed in parse_fx10_local_object, which has an array index. */ + if (offset >= data_size || !require_space(offset, 2, sizeof(DWORD), data_size)) + { + WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size); + return E_FAIL; + } data_ptr = data + offset; read_dword(&data_ptr, &offset); read_dword(&data_ptr, &variable_idx); - TRACE("Variable name %s[%u].\n", debugstr_a(data + offset), variable_idx);
- variable = e->lpVtbl->GetVariableByName(e, data + offset); + if (!fx10_get_string(data, data_size, offset, &name, &name_len)) + { + WARN("Failed to get variable name.\n"); + return E_FAIL; + } + + TRACE("Variable name %s[%u].\n", debugstr_a(name), variable_idx); + + variable = e->lpVtbl->GetVariableByName(e, name); break;
case D3D10_EOO_ANONYMOUS_SHADER: @@ -1370,6 +1408,11 @@ static HRESULT parse_fx10_object(struct d3d10_effect_object *o, const char **ptr return E_FAIL; }
+ if (offset >= data_size || !require_space(offset, 1, sizeof(DWORD), data_size)) + { + WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size); + return E_FAIL; + } data_ptr = data + offset; read_dword(&data_ptr, &offset); TRACE("Effect object starts at offset %#x.\n", offset); @@ -1527,8 +1570,8 @@ static HRESULT parse_fx10_pass(const char *data, size_t data_size,
o->pass = p;
- hr = parse_fx10_object(o, ptr, data); - if (FAILED(hr)) return hr; + if (FAILED(hr = parse_fx10_object(data, data_size, ptr, o))) + return hr; }
return hr;