From 2c82697c1b982ede974e34b36c37c24f55d2ccb1 Mon Sep 17 00:00:00 2001 From: Chuck Walbourn Date: Fri, 27 Jul 2018 01:02:56 -0700 Subject: [PATCH] Improved validation where WIC requires a cast to UINT for pitch/imageSize --- DirectXTex/BCDirectCompute.cpp | 7 ++++++- DirectXTex/DirectXTexConvert.cpp | 4 ++++ DirectXTex/DirectXTexD3D12.cpp | 7 +++---- DirectXTex/DirectXTexFlipRotate.cpp | 4 ++++ DirectXTex/DirectXTexMipmaps.cpp | 9 +++++++++ DirectXTex/DirectXTexResize.cpp | 4 ++++ DirectXTex/DirectXTexWIC.cpp | 9 +++++++++ 7 files changed, 39 insertions(+), 5 deletions(-) diff --git a/DirectXTex/BCDirectCompute.cpp b/DirectXTex/BCDirectCompute.cpp index 940618c..fb06a4a 100644 --- a/DirectXTex/BCDirectCompute.cpp +++ b/DirectXTex/BCDirectCompute.cpp @@ -232,7 +232,12 @@ HRESULT GPUCompressBC::Prepare(size_t width, size_t height, DWORD flags, DXGI_FO return E_POINTER; // Create structured buffers - size_t bufferSize = num_blocks * sizeof(BufferBC6HBC7); + uint64_t sizeInBytes = uint64_t(num_blocks) * sizeof(BufferBC6HBC7); + if (sizeInBytes >= UINT32_MAX) + return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + + auto bufferSize = static_cast(sizeInBytes); + { D3D11_BUFFER_DESC desc = {}; desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; diff --git a/DirectXTex/DirectXTexConvert.cpp b/DirectXTex/DirectXTexConvert.cpp index 61cf7cf..41858d5 100644 --- a/DirectXTex/DirectXTexConvert.cpp +++ b/DirectXTex/DirectXTexConvert.cpp @@ -4445,6 +4445,10 @@ namespace return E_UNEXPECTED; } + if (srcImage.rowPitch > UINT32_MAX || srcImage.slicePitch > UINT32_MAX + || destImage.rowPitch > UINT32_MAX || destImage.slicePitch > UINT32_MAX) + return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + ComPtr source; hr = pWIC->CreateBitmapFromMemory(static_cast(srcImage.width), static_cast(srcImage.height), pfGUID, static_cast(srcImage.rowPitch), static_cast(srcImage.slicePitch), diff --git a/DirectXTex/DirectXTexD3D12.cpp b/DirectXTex/DirectXTexD3D12.cpp index 53a5cd1..f33e4c6 100644 --- a/DirectXTex/DirectXTexD3D12.cpp +++ b/DirectXTex/DirectXTexD3D12.cpp @@ -349,7 +349,7 @@ bool DirectX::IsSupportedTexture( return false; { - auto numberOfResources = static_cast(arraySize * metadata.mipLevels); + uint64_t numberOfResources = uint64_t(arraySize) * uint64_t(metadata.mipLevels); if (numberOfResources > D3D12_REQ_SUBRESOURCES) return false; } @@ -378,7 +378,7 @@ bool DirectX::IsSupportedTexture( } { - auto numberOfResources = static_cast(arraySize * metadata.mipLevels); + uint64_t numberOfResources = uint64_t(arraySize) * uint64_t(metadata.mipLevels); if (numberOfResources > D3D12_REQ_SUBRESOURCES) return false; } @@ -395,8 +395,7 @@ bool DirectX::IsSupportedTexture( return false; { - auto numberOfResources = static_cast(metadata.mipLevels); - if (numberOfResources > D3D12_REQ_SUBRESOURCES) + if (metadata.mipLevels > D3D12_REQ_SUBRESOURCES) return false; } break; diff --git a/DirectXTex/DirectXTexFlipRotate.cpp b/DirectXTex/DirectXTexFlipRotate.cpp index 50d6dd3..8870dbf 100644 --- a/DirectXTex/DirectXTexFlipRotate.cpp +++ b/DirectXTex/DirectXTexFlipRotate.cpp @@ -35,6 +35,10 @@ namespace if (!pWIC) return E_NOINTERFACE; + if (srcImage.rowPitch > UINT32_MAX || srcImage.slicePitch > UINT32_MAX + || destImage.rowPitch > UINT32_MAX || destImage.slicePitch > UINT32_MAX) + return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + ComPtr source; HRESULT hr = pWIC->CreateBitmapFromMemory(static_cast(srcImage.width), static_cast(srcImage.height), pfGUID, static_cast(srcImage.rowPitch), static_cast(srcImage.slicePitch), diff --git a/DirectXTex/DirectXTexMipmaps.cpp b/DirectXTex/DirectXTexMipmaps.cpp index ae1c9c7..ac37679 100644 --- a/DirectXTex/DirectXTexMipmaps.cpp +++ b/DirectXTex/DirectXTexMipmaps.cpp @@ -361,6 +361,9 @@ namespace DirectX if (SUCCEEDED(hr)) { + if (img->rowPitch > UINT32_MAX || img->slicePitch > UINT32_MAX) + return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + ComPtr wicBitmap; hr = EnsureWicBitmapPixelFormat(pWIC, resizedColorWithAlpha.Get(), filter, desiredPixelFormat, wicBitmap.GetAddressOf()); if (SUCCEEDED(hr)) @@ -468,6 +471,9 @@ namespace size_t width = baseImage.width; size_t height = baseImage.height; + if (baseImage.rowPitch > UINT32_MAX || baseImage.slicePitch > UINT32_MAX) + return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + ComPtr source; HRESULT hr = pWIC->CreateBitmapFromMemory(static_cast(width), static_cast(height), pfGUID, static_cast(baseImage.rowPitch), static_cast(baseImage.slicePitch), @@ -536,6 +542,9 @@ namespace if (FAILED(hr)) return hr; + if (img->rowPitch > UINT32_MAX || img->slicePitch > UINT32_MAX) + return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + hr = scaler->Initialize(source.Get(), static_cast(width), static_cast(height), _GetWICInterp(filter)); if (FAILED(hr)) return hr; diff --git a/DirectXTex/DirectXTexResize.cpp b/DirectXTex/DirectXTexResize.cpp index d4db78e..5988a6a 100644 --- a/DirectXTex/DirectXTexResize.cpp +++ b/DirectXTex/DirectXTexResize.cpp @@ -56,6 +56,10 @@ namespace if (FAILED(hr)) return hr; + if (srcImage.rowPitch > UINT32_MAX || srcImage.slicePitch > UINT32_MAX + || destImage.rowPitch > UINT32_MAX || destImage.slicePitch > UINT32_MAX) + return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + ComPtr source; hr = pWIC->CreateBitmapFromMemory(static_cast(srcImage.width), static_cast(srcImage.height), pfGUID, static_cast(srcImage.rowPitch), static_cast(srcImage.slicePitch), diff --git a/DirectXTex/DirectXTexWIC.cpp b/DirectXTex/DirectXTexWIC.cpp index 446c059..8ce57c2 100644 --- a/DirectXTex/DirectXTexWIC.cpp +++ b/DirectXTex/DirectXTexWIC.cpp @@ -390,6 +390,9 @@ namespace if (!pWIC) return E_NOINTERFACE; + if (img->rowPitch > UINT32_MAX || img->slicePitch > UINT32_MAX) + return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + if (memcmp(&convertGUID, &GUID_NULL, sizeof(GUID)) == 0) { hr = frame->CopyPixels(nullptr, static_cast(img->rowPitch), static_cast(img->slicePitch), img->pixels); @@ -459,6 +462,9 @@ namespace if (!img) return E_POINTER; + if (img->rowPitch > UINT32_MAX || img->slicePitch > UINT32_MAX) + return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + ComPtr frame; hr = decoder->GetFrame(static_cast(index), frame.GetAddressOf()); if (FAILED(hr)) @@ -687,6 +693,9 @@ namespace if ((image.width > UINT32_MAX) || (image.height > UINT32_MAX)) return E_INVALIDARG; + if (image.rowPitch > UINT32_MAX || image.slicePitch > UINT32_MAX) + return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + hr = frame->SetSize(static_cast(image.width), static_cast(image.height)); if (FAILED(hr)) return hr;