1
0
mirror of https://github.com/microsoft/DirectXTex synced 2024-11-09 14:30:05 +00:00

texconv: Fix PFM reader to avoid overread of buffer (#413)

* texconv: Fix PFM reader to avoid overread of buffer

* More code review

* Max memory usage

* YAML fix
This commit is contained in:
Chuck Walbourn 2023-11-09 20:10:12 -08:00 committed by GitHub
parent 3aebd48c6f
commit 282812b973
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 25 deletions

View File

@ -121,14 +121,19 @@ namespace
_In_ ID3D12CommandQueue* pCommandQ, _In_ ID3D12CommandQueue* pCommandQ,
_In_ ID3D12Resource* pSource, _In_ ID3D12Resource* pSource,
const D3D12_RESOURCE_DESC& desc, const D3D12_RESOURCE_DESC& desc,
ComPtr<ID3D12Resource>& pStaging, _COM_Outptr_ ID3D12Resource** pStaging,
std::unique_ptr<uint8_t[]>& layoutBuff, std::unique_ptr<uint8_t[]>& layoutBuff,
UINT& numberOfPlanes, UINT& numberOfPlanes,
UINT& numberOfResources, UINT& numberOfResources,
D3D12_RESOURCE_STATES beforeState, D3D12_RESOURCE_STATES beforeState,
D3D12_RESOURCE_STATES afterState) noexcept D3D12_RESOURCE_STATES afterState) noexcept
{ {
if (!pCommandQ || !pSource) if (pStaging)
{
*pStaging = nullptr;
}
if (!pCommandQ || !pSource || !pStaging)
return E_INVALIDARG; return E_INVALIDARG;
numberOfPlanes = D3D12GetFormatPlaneCount(device, desc.Format); numberOfPlanes = D3D12GetFormatPlaneCount(device, desc.Format);
@ -170,7 +175,8 @@ namespace
if (SUCCEEDED(hr) && sourceHeapProperties.Type == D3D12_HEAP_TYPE_READBACK) if (SUCCEEDED(hr) && sourceHeapProperties.Type == D3D12_HEAP_TYPE_READBACK)
{ {
// Handle case where the source is already a staging texture we can use directly // Handle case where the source is already a staging texture we can use directly
pStaging = pSource; *pStaging = pSource;
pSource->AddRef();
return S_OK; return S_OK;
} }
@ -267,11 +273,11 @@ namespace
&bufferDesc, &bufferDesc,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_DEST,
nullptr, nullptr,
IID_GRAPHICS_PPV_ARGS(pStaging.GetAddressOf())); IID_GRAPHICS_PPV_ARGS(pStaging));
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
assert(pStaging); assert(*pStaging);
// Transition the resource if necessary // Transition the resource if necessary
TransitionResource(commandList.Get(), pSource, beforeState, D3D12_RESOURCE_STATE_COPY_SOURCE); TransitionResource(commandList.Get(), pSource, beforeState, D3D12_RESOURCE_STATE_COPY_SOURCE);
@ -279,7 +285,7 @@ namespace
// Get the copy target location // Get the copy target location
for (UINT j = 0; j < numberOfResources; ++j) for (UINT j = 0; j < numberOfResources; ++j)
{ {
const CD3DX12_TEXTURE_COPY_LOCATION copyDest(pStaging.Get(), pLayout[j]); const CD3DX12_TEXTURE_COPY_LOCATION copyDest(*pStaging, pLayout[j]);
const CD3DX12_TEXTURE_COPY_LOCATION copySrc(copySource.Get(), j); const CD3DX12_TEXTURE_COPY_LOCATION copySrc(copySource.Get(), j);
commandList->CopyTextureRegion(&copyDest, 0, 0, 0, &copySrc, nullptr); commandList->CopyTextureRegion(&copyDest, 0, 0, 0, &copySrc, nullptr);
} }
@ -734,7 +740,7 @@ HRESULT DirectX::CaptureTexture(
pCommandQueue, pCommandQueue,
pSource, pSource,
desc, desc,
pStaging, pStaging.GetAddressOf(),
layoutBuff, layoutBuff,
numberOfPlanes, numberOfPlanes,
numberOfResources, numberOfResources,

View File

@ -687,11 +687,16 @@ namespace
_In_ ID3D12Resource* pSource, _In_ ID3D12Resource* pSource,
UINT64 srcPitch, UINT64 srcPitch,
const D3D12_RESOURCE_DESC& desc, const D3D12_RESOURCE_DESC& desc,
ComPtr<ID3D12Resource>& pStaging, _COM_Outptr_ ID3D12Resource** pStaging,
D3D12_RESOURCE_STATES beforeState, D3D12_RESOURCE_STATES beforeState,
D3D12_RESOURCE_STATES afterState) noexcept D3D12_RESOURCE_STATES afterState) noexcept
{ {
if (!pCommandQ || !pSource) if (pStaging)
{
*pStaging = nullptr;
}
if (!pCommandQ || !pSource || !pStaging)
return E_INVALIDARG; return E_INVALIDARG;
if (desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D) if (desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D)
@ -709,7 +714,8 @@ namespace
if (SUCCEEDED(hr) && sourceHeapProperties.Type == D3D12_HEAP_TYPE_READBACK) if (SUCCEEDED(hr) && sourceHeapProperties.Type == D3D12_HEAP_TYPE_READBACK)
{ {
// Handle case where the source is already a staging texture we can use directly // Handle case where the source is already a staging texture we can use directly
pStaging = pSource; *pStaging = pSource;
pSource->AddRef();
return S_OK; return S_OK;
} }
@ -801,11 +807,11 @@ namespace
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_DEST,
nullptr, nullptr,
IID_ID3D12Resource, IID_ID3D12Resource,
reinterpret_cast<void**>(pStaging.ReleaseAndGetAddressOf())); reinterpret_cast<void**>(pStaging));
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
assert(pStaging); assert(*pStaging);
// Transition the resource if necessary // Transition the resource if necessary
TransitionResource(commandList.Get(), pSource, beforeState, D3D12_RESOURCE_STATE_COPY_SOURCE); TransitionResource(commandList.Get(), pSource, beforeState, D3D12_RESOURCE_STATE_COPY_SOURCE);
@ -818,7 +824,7 @@ namespace
bufferFootprint.Footprint.RowPitch = static_cast<UINT>(srcPitch); bufferFootprint.Footprint.RowPitch = static_cast<UINT>(srcPitch);
bufferFootprint.Footprint.Format = desc.Format; bufferFootprint.Footprint.Format = desc.Format;
const CD3DX12_TEXTURE_COPY_LOCATION copyDest(pStaging.Get(), bufferFootprint); const CD3DX12_TEXTURE_COPY_LOCATION copyDest(*pStaging, bufferFootprint);
const CD3DX12_TEXTURE_COPY_LOCATION copySrc(copySource.Get(), 0); const CD3DX12_TEXTURE_COPY_LOCATION copySrc(copySource.Get(), 0);
// Copy the texture // Copy the texture
@ -929,7 +935,7 @@ HRESULT DirectX::SaveDDSTextureToFile(
return HRESULT_E_ARITHMETIC_OVERFLOW; return HRESULT_E_ARITHMETIC_OVERFLOW;
ComPtr<ID3D12Resource> pStaging; ComPtr<ID3D12Resource> pStaging;
HRESULT hr = CaptureTexture(device.Get(), pCommandQ, pSource, dstRowPitch, desc, pStaging, beforeState, afterState); HRESULT hr = CaptureTexture(device.Get(), pCommandQ, pSource, dstRowPitch, desc, pStaging.GetAddressOf(), beforeState, afterState);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -1157,7 +1163,7 @@ HRESULT DirectX::SaveWICTextureToFile(
return HRESULT_E_ARITHMETIC_OVERFLOW; return HRESULT_E_ARITHMETIC_OVERFLOW;
ComPtr<ID3D12Resource> pStaging; ComPtr<ID3D12Resource> pStaging;
HRESULT hr = CaptureTexture(device.Get(), pCommandQ, pSource, dstRowPitch, desc, pStaging, beforeState, afterState); HRESULT hr = CaptureTexture(device.Get(), pCommandQ, pSource, dstRowPitch, desc, pStaging.GetAddressOf(), beforeState, afterState);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;

View File

@ -264,7 +264,7 @@ HRESULT __cdecl LoadFromPortablePixMap(
if (u > INT32_MAX) if (u > INT32_MAX)
{ {
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
} }
width = u; width = u;
@ -277,7 +277,13 @@ HRESULT __cdecl LoadFromPortablePixMap(
if (u > INT32_MAX) if (u > INT32_MAX)
{ {
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
}
uint64_t sizeBytes = uint64_t(width) * uint64_t(u);
if (sizeBytes > UINT32_MAX)
{
HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
} }
if (metadata) if (metadata)
@ -473,7 +479,7 @@ HRESULT __cdecl LoadFromPortablePixMapHDR(
size_t len = 0; size_t len = 0;
while (pfmSize > 0) while (pfmSize > 0)
{ {
len = FindEOL(pData, 256); len = FindEOL(pData, std::min<size_t>(256, pfmSize));
if (!len) if (!len)
return E_FAIL; return E_FAIL;
@ -498,9 +504,15 @@ HRESULT __cdecl LoadFromPortablePixMapHDR(
if (sscanf_s(dataStr, "%zu %zu%s", &width, &height, junkStr, 256) != 2) if (sscanf_s(dataStr, "%zu %zu%s", &width, &height, junkStr, 256) != 2)
return E_FAIL; return E_FAIL;
if ((width > INT32_MAX) || (height > UINT32_MAX)) if ((width > INT32_MAX) || (height > INT32_MAX))
{ {
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE); return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
}
uint64_t sizeBytes = uint64_t(width) * uint64_t(height);
if (sizeBytes > UINT32_MAX)
{
HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
} }
pData += len + 1; pData += len + 1;
@ -516,7 +528,7 @@ HRESULT __cdecl LoadFromPortablePixMapHDR(
len = 0; len = 0;
while (pfmSize > 0) while (pfmSize > 0)
{ {
len = FindEOL(pData, 256); len = FindEOL(pData, std::min<size_t>(256, pfmSize));
if (!len) if (!len)
return E_FAIL; return E_FAIL;
@ -550,8 +562,8 @@ HRESULT __cdecl LoadFromPortablePixMapHDR(
if (!pfmSize) if (!pfmSize)
return E_FAIL; return E_FAIL;
const size_t scanline = width * (half16 ? sizeof(uint16_t) : sizeof(float)) * (monochrome ? 1 : 3); const uint64_t scanline = uint64_t(width) * (half16 ? sizeof(uint16_t) : sizeof(float)) * (monochrome ? 1 : 3);
if (pfmSize < scanline * height) if (uint64_t(pfmSize) < (scanline * uint64_t(height)))
return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF); return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF);
if (metadata) if (metadata)
@ -570,7 +582,6 @@ HRESULT __cdecl LoadFromPortablePixMapHDR(
auto img = image.GetImage(0, 0, 0); auto img = image.GetImage(0, 0, 0);
if (half16) if (half16)
{ {
auto sptr = reinterpret_cast<const uint16_t*>(pData); auto sptr = reinterpret_cast<const uint16_t*>(pData);

View File

@ -32,6 +32,8 @@ pool:
jobs: jobs:
- job: SDL_BUILD - job: SDL_BUILD
displayName: 'Build using required SDL tools' displayName: 'Build using required SDL tools'
workspace:
clean: all
steps: steps:
- checkout: self - checkout: self
clean: true clean: true

View File

@ -12,7 +12,10 @@
"OneFuzzJobs": [ "OneFuzzJobs": [
{ {
"ProjectName": "Direct3D", "ProjectName": "Direct3D",
"TargetName": "DirectXTex" "TargetName": "DirectXTex",
"TargetOptions": [
"-rss_limit_mb=4096"
]
} }
], ],
"JobDependencies": [ "JobDependencies": [