Skip to content

Commit 3779c5a

Browse files
committed
Improve heap safety in CProxyDirect3DVertexBuffer::Lock
Pre-sized the fallback staging buffer during construction so its backing allocation never moves while a caller is writing through the pointer we returned. Added guard at the top of Lock: if a previous fallback session hasn’t finished, we simply return D3DERR_WASSTILLDRAWING Keep the fallback tracking zeroed only after sure no retry is pending, and leave its storage allocated so later locks stay in-bounds without reallocations. Now, the fallback pointer is always within a stable buffer, and it rejects overlapping fallback locks so interfering software hooks can’t trigger resizing under a writer *Note: Most problems with vertex buffer locking (now and before) come from 3rd party hooks, like recording tools and overlays
1 parent 53097a6 commit 3779c5a

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

Client/core/DXHook/CProxyDirect3DVertexBuffer.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ CProxyDirect3DVertexBuffer::CProxyDirect3DVertexBuffer(IDirect3DDevice9* InD3DDe
3636
m_fallbackOffset = 0;
3737
m_fallbackSize = 0;
3838
m_fallbackFlags = 0;
39-
m_fallbackStorage.clear();
39+
m_fallbackStorage.resize(std::max<size_t>(static_cast<size_t>(m_iMemUsed), static_cast<size_t>(1)));
4040

4141
m_stats.iCurrentCount++;
4242
m_stats.iCurrentBytes += m_iMemUsed;
@@ -122,14 +122,26 @@ HRESULT CProxyDirect3DVertexBuffer::Lock(UINT OffsetToLock, UINT SizeToLock, voi
122122

123123
SharedUtil::CAutoCSLock fallbackGuard(m_fallbackCS);
124124

125+
125126
if (m_bFallbackActive)
126127
{
127-
m_bFallbackActive = false;
128-
m_fallbackOffset = 0;
129-
m_fallbackSize = 0;
130-
m_fallbackFlags = 0;
128+
if (ppbData)
129+
*ppbData = nullptr;
130+
131+
SString strMessage("Lock VertexBuffer: fallback still pending - refusing new lock (Offset:%x Size:%x Flags:%08x)", m_fallbackOffset, m_fallbackSize,
132+
m_fallbackFlags);
133+
WriteDebugEvent(strMessage);
134+
AddReportLog(8624, strMessage);
135+
CCore::GetSingleton().LogEvent(624, "Lock VertexBuffer", "", strMessage);
136+
137+
return D3DERR_WASSTILLDRAWING;
131138
}
132139

140+
m_bFallbackActive = false;
141+
m_fallbackOffset = 0;
142+
m_fallbackSize = 0;
143+
m_fallbackFlags = 0;
144+
133145
*ppbData = nullptr;
134146
HRESULT hr = DoLock(OffsetToLock, SizeToLock, ppbData, Flags);
135147
HRESULT originalHr = hr;

0 commit comments

Comments
 (0)