From 6a7e77ce1db6fe52fce8b5bdbc0df90a0183eef5 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Thu, 20 Dec 2012 14:35:47 +0100 Subject: [PATCH] Prevent crashes on bad vertex / index addresses --- GPU/GLES/DisplayListInterpreter.cpp | 12 ++++++++++++ GPU/GLES/VertexDecoder.h | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index 2202a21163..cc772c2ac9 100644 --- a/GPU/GLES/DisplayListInterpreter.cpp +++ b/GPU/GLES/DisplayListInterpreter.cpp @@ -400,12 +400,24 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) }; DEBUG_LOG(G3D, "DL DrawPrim type: %s count: %i vaddr= %08x, iaddr= %08x", type<7 ? types[type] : "INVALID", count, gstate_c.vertexAddr, gstate_c.indexAddr); + if (!Memory::IsValidAddress(gstate_c.vertexAddr)) + { + ERROR_LOG(G3D, "Bad vertex address %08x!", gstate_c.vertexAddr); + break; + } // TODO: Split this so that we can collect sequences of primitives, can greatly speed things up // on platforms where draw calls are expensive like mobile and D3D void *verts = Memory::GetPointer(gstate_c.vertexAddr); void *inds = 0; if ((gstate.vertType & GE_VTYPE_IDX_MASK) != GE_VTYPE_IDX_NONE) + { + if (!Memory::IsValidAddress(gstate_c.indexAddr)) + { + ERROR_LOG(G3D, "Bad index address %08x!", gstate_c.indexAddr); + break; + } inds = Memory::GetPointer(gstate_c.indexAddr); + } // Seems we have to advance the vertex addr, at least in some cases. // Question: Should we also advance the index addr? diff --git a/GPU/GLES/VertexDecoder.h b/GPU/GLES/VertexDecoder.h index f8cdddf232..bc2c14786c 100644 --- a/GPU/GLES/VertexDecoder.h +++ b/GPU/GLES/VertexDecoder.h @@ -192,6 +192,9 @@ public: pos[i] = p[i] / 127.0f; } break; + default: + ERROR_LOG(G3D, "Reader: Unsupported Pos Format"); + break; } } @@ -214,6 +217,9 @@ public: nrm[i] = p[i] / 127.0f; } break; + default: + ERROR_LOG(G3D, "Reader: Unsupported Nrm Format"); + break; } } @@ -221,6 +227,9 @@ public: switch (decFmt_.uvfmt) { case DEC_FLOAT_2: memcpy(uv, data_ + decFmt_.uvoff, 8); break; + default: + ERROR_LOG(G3D, "Reader: Unsupported UV Format"); + break; } } @@ -235,6 +244,9 @@ public: break; case DEC_FLOAT_4: memcpy(color, data_ + decFmt_.c0off, 16); break; + default: + ERROR_LOG(G3D, "Reader: Unsupported C0 Format"); + break; } } @@ -249,6 +261,9 @@ public: break; case DEC_FLOAT_4: memcpy(color, data_ + decFmt_.c1off, 16); break; + default: + ERROR_LOG(G3D, "Reader: Unsupported C1 Format"); + break; } } @@ -258,12 +273,18 @@ public: case DEC_FLOAT_2: memcpy(weights, data_ + decFmt_.w0off, 8); break; case DEC_FLOAT_3: memcpy(weights, data_ + decFmt_.w0off, 12); break; case DEC_FLOAT_4: memcpy(weights, data_ + decFmt_.w0off, 16); break; + default: + ERROR_LOG(G3D, "Reader: Unsupported W0 Format"); + break; } switch (decFmt_.w1fmt) { case DEC_FLOAT_1: memcpy(weights + 4, data_ + decFmt_.w1off, 4); break; case DEC_FLOAT_2: memcpy(weights + 4, data_ + decFmt_.w1off, 8); break; case DEC_FLOAT_3: memcpy(weights + 4, data_ + decFmt_.w1off, 12); break; case DEC_FLOAT_4: memcpy(weights + 4, data_ + decFmt_.w1off, 16); break; + default: + ERROR_LOG(G3D, "Reader: Unsupported W1 Format"); + break; } }