Henri Verbeet : d3d10: Validate offsets and sizes in parse_dxbc() (AFL).

Alexandre Julliard julliard at winehq.org
Wed May 25 10:41:09 CDT 2016


Module: wine
Branch: master
Commit: 994c5618b1e1e5b132e09f0960b3bf2268879817
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=994c5618b1e1e5b132e09f0960b3bf2268879817

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Tue May 24 19:46:42 2016 +0200

d3d10: Validate offsets and sizes in parse_dxbc() (AFL).

Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/d3d10/d3d10_private.h |  5 +++++
 dlls/d3d10/utils.c         | 12 ++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h
index 232399f..0e27dfe 100644
--- a/dlls/d3d10/d3d10_private.h
+++ b/dlls/d3d10/d3d10_private.h
@@ -294,6 +294,11 @@ static inline void write_dword(char **ptr, DWORD d)
     *ptr += sizeof(d);
 }
 
+static inline BOOL require_space(size_t offset, size_t size, size_t data_size)
+{
+    return data_size - offset >= size;
+}
+
 void skip_dword_unknown(const char *location, const char **ptr, unsigned int count) DECLSPEC_HIDDEN;
 void write_dword_unknown(char **ptr, DWORD d) DECLSPEC_HIDDEN;
 
diff --git a/dlls/d3d10/utils.c b/dlls/d3d10/utils.c
index 9ffff13..618fdee 100644
--- a/dlls/d3d10/utils.c
+++ b/dlls/d3d10/utils.c
@@ -217,11 +217,23 @@ HRESULT parse_dxbc(const char *data, SIZE_T data_size,
         read_dword(&ptr, &chunk_offset);
         TRACE("chunk %u at offset %#x\n", i, chunk_offset);
 
+        if (chunk_offset >= data_size || !require_space(chunk_offset, 2 * sizeof(DWORD), data_size))
+        {
+            WARN("Invalid chunk offset %#x (data size %#lx).\n", chunk_offset, data_size);
+            return E_FAIL;
+        }
+
         chunk_ptr = data + chunk_offset;
 
         read_dword(&chunk_ptr, &chunk_tag);
         read_dword(&chunk_ptr, &chunk_size);
 
+        if (!require_space(chunk_ptr - data, chunk_size, data_size))
+        {
+            WARN("Invalid chunk size %#x (data size %#lx, chunk offset %#x).\n", chunk_size, data_size, chunk_offset);
+            return E_FAIL;
+        }
+
         hr = chunk_handler(chunk_ptr, chunk_size, chunk_tag, ctx);
         if (FAILED(hr)) break;
     }




More information about the wine-cvs mailing list