From 678ccc721db2facf241e6204d52bfa2b792584ad Mon Sep 17 00:00:00 2001 From: WinterSnowfall Date: Fri, 11 Oct 2024 23:33:38 +0300 Subject: [PATCH] [d3d9] Validate pRect dimensions with LockRect --- src/d3d9/d3d9_surface.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/d3d9/d3d9_surface.cpp b/src/d3d9/d3d9_surface.cpp index 7c6f29abd..3fcfcac89 100644 --- a/src/d3d9/d3d9_surface.cpp +++ b/src/d3d9/d3d9_surface.cpp @@ -124,7 +124,33 @@ namespace dxvk { return D3DERR_INVALIDCALL; D3DBOX box; - if (pRect != nullptr) { + + if (unlikely(pRect != nullptr)) { + D3DRESOURCETYPE type = m_texture->GetType(); + auto& desc = *(m_texture->Desc()); + D3D9_FORMAT_BLOCK_SIZE blockSize = GetFormatBlockSize(desc.Format); + + bool isBlockAlignedFormat = blockSize.Width > 0 && blockSize.Height > 0; + + // The boundaries of pRect are validated for D3DPOOL_DEFAULT surfaces + // with formats which need to be block aligned (mip 0), surfaces created via + // CreateImageSurface and D3D8 cube textures outside of D3DPOOL_DEFAULT + if ((m_mipLevel == 0 && isBlockAlignedFormat && desc.Pool == D3DPOOL_DEFAULT) + || (desc.Pool == D3DPOOL_SYSTEMMEM && type == D3DRTYPE_SURFACE) + || (m_texture->Device()->IsD3D8Compatible() && + desc.Pool != D3DPOOL_DEFAULT && type == D3DRTYPE_CUBETEXTURE)) { + // Negative coordinates + if (pRect->left < 0 || pRect->right < 0 + || pRect->top < 0 || pRect->bottom < 0 + // Negative or zero length dimensions + || pRect->right - pRect->left <= 0 + || pRect->bottom - pRect->top <= 0 + // Exceeding surface dimensions + || static_cast(pRect->right) > desc.Width + || static_cast(pRect->bottom) > desc.Height) + return D3DERR_INVALIDCALL; + } + box.Left = pRect->left; box.Right = pRect->right; box.Top = pRect->top;