[PATCH 3/5] d3d10: Validate offsets in parse_fx10_object() (AFL).
Henri Verbeet
hverbeet at codeweavers.com
Wed May 25 13:04:03 CDT 2016
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
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..b0e0889 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 %#x (data size %#lx).\n", *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;
--
2.1.4
More information about the wine-patches
mailing list