[PATCH 4/5] d3d10: Validate offsets in parse_shader() (AFL).

Henri Verbeet hverbeet at codeweavers.com
Sun Jul 10 08:09:19 CDT 2016


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/d3d10/effect.c | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
index ff00aa1..4736fa9 100644
--- a/dlls/d3d10/effect.c
+++ b/dlls/d3d10/effect.c
@@ -475,12 +475,11 @@ static HRESULT shader_chunk_handler(const char *data, DWORD data_size, DWORD tag
     return S_OK;
 }
 
-static HRESULT parse_shader(ID3D10EffectVariable *variable, const char *data)
+static HRESULT parse_fx10_shader(const char *data, size_t data_size, DWORD offset, struct d3d10_effect_variable *v)
 {
-    struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable(variable);
     ID3D10Device *device = v->effect->device;
-    const char *ptr = data;
     DWORD dxbc_size;
+    const char *ptr;
     HRESULT hr;
 
     if (v->effect->used_shader_current >= v->effect->used_shader_count)
@@ -492,11 +491,22 @@ static HRESULT parse_shader(ID3D10EffectVariable *variable, const char *data)
     v->effect->used_shaders[v->effect->used_shader_current] = v;
     ++v->effect->used_shader_current;
 
-    if (!ptr) return S_OK;
+    if (offset >= data_size || !require_space(offset, 1, sizeof(dxbc_size), data_size))
+    {
+        WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size);
+        return E_FAIL;
+    }
 
+    ptr = data + offset;
     read_dword(&ptr, &dxbc_size);
     TRACE("dxbc size: %#x\n", dxbc_size);
 
+    if (!require_space(ptr - data, 1, dxbc_size, data_size))
+    {
+        WARN("Invalid dxbc size %#x (data size %#lx, offset %#x).\n", offset, (long)data_size, offset);
+        return E_FAIL;
+    }
+
     /* We got a shader VertexShader vs = NULL, so it is fine to skip this. */
     if (!dxbc_size) return S_OK;
 
@@ -1304,6 +1314,7 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size,
     HRESULT hr;
     struct d3d10_effect *effect = o->pass->technique->effect;
     ID3D10Effect *e = &effect->ID3D10Effect_iface;
+    struct d3d10_effect_variable *v;
     DWORD tmp, variable_idx = 0;
     const char *name;
     size_t name_len;
@@ -1431,12 +1442,12 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size,
             read_dword(&data_ptr, &offset);
             TRACE("Effect object starts at offset %#x.\n", offset);
 
-            data_ptr = data + offset;
-
-            hr = parse_fx10_anonymous_shader(effect, &effect->anonymous_shaders[effect->anonymous_shader_current], o->type);
-            if (FAILED(hr)) return hr;
+            if (FAILED(hr = parse_fx10_anonymous_shader(effect,
+                    &effect->anonymous_shaders[effect->anonymous_shader_current], o->type)))
+                return hr;
 
-            variable = &effect->anonymous_shaders[effect->anonymous_shader_current].shader.ID3D10EffectVariable_iface;
+            v = &effect->anonymous_shaders[effect->anonymous_shader_current].shader;
+            variable = &v->ID3D10EffectVariable_iface;
             ++effect->anonymous_shader_current;
 
             switch (o->type)
@@ -1444,7 +1455,7 @@ static HRESULT parse_fx10_object(const char *data, size_t data_size,
                 case D3D10_EOT_VERTEXSHADER:
                 case D3D10_EOT_PIXELSHADER:
                 case D3D10_EOT_GEOMETRYSHADER:
-                    if (FAILED(hr = parse_shader(variable, data_ptr)))
+                    if (FAILED(hr = parse_fx10_shader(data, data_size, offset, v)))
                         return hr;
                     break;
 
@@ -1800,8 +1811,8 @@ static HRESULT parse_fx10_local_variable(const char *data, size_t data_size,
                 read_dword(ptr, &shader_offset);
                 TRACE("Shader offset: %#x.\n", shader_offset);
 
-                hr = parse_shader(&var->ID3D10EffectVariable_iface, data + shader_offset);
-                if (FAILED(hr)) return hr;
+                if (FAILED(hr = parse_fx10_shader(data, data_size, shader_offset, var)))
+                    return hr;
             }
             break;
 
-- 
2.1.4




More information about the wine-patches mailing list