From 3154a66b412b310e9e153014644d39604c4eceaa Mon Sep 17 00:00:00 2001 From: Chuck Walbourn Date: Tue, 12 Dec 2023 13:17:51 -0800 Subject: [PATCH] PPM TGA HDR bounds updates on readers (#421) --- DirectXTex/DirectXTexHDR.cpp | 16 ++++++++++++++++ DirectXTex/DirectXTexP.h | 1 + DirectXTex/DirectXTexTGA.cpp | 6 ++++++ Texconv/PortablePixMap.cpp | 21 +++++++++++---------- build/OneFuzzConfig.json | 5 ++++- build/onefuzz-setup.ps1 | 17 ----------------- 6 files changed, 38 insertions(+), 28 deletions(-) diff --git a/DirectXTex/DirectXTexHDR.cpp b/DirectXTex/DirectXTexHDR.cpp index da1cb28..bdb3191 100644 --- a/DirectXTex/DirectXTexHDR.cpp +++ b/DirectXTex/DirectXTexHDR.cpp @@ -247,6 +247,11 @@ namespace return E_FAIL; } + if (height > UINT16_MAX) + { + return HRESULT_E_NOT_SUPPORTED; + } + const char* ptr = orientation + 2; while (*ptr != 0 && *ptr != '-' && *ptr != '+') ++ptr; @@ -279,6 +284,11 @@ namespace return E_FAIL; } + if (width > UINT16_MAX) + { + return HRESULT_E_NOT_SUPPORTED; + } + info += len + 1; size -= len + 1; @@ -287,6 +297,12 @@ namespace return HRESULT_E_INVALID_DATA; } + uint64_t sizeBytes = uint64_t(width) * uint64_t(height) * sizeof(float) * 4; + if (sizeBytes > UINT32_MAX) + { + return HRESULT_E_ARITHMETIC_OVERFLOW; + } + if (size == 0) { return E_FAIL; diff --git a/DirectXTex/DirectXTexP.h b/DirectXTex/DirectXTexP.h index 96e1c9c..d733464 100644 --- a/DirectXTex/DirectXTexP.h +++ b/DirectXTex/DirectXTexP.h @@ -133,6 +133,7 @@ #include #include +#include #include #include #include diff --git a/DirectXTex/DirectXTexTGA.cpp b/DirectXTex/DirectXTexTGA.cpp index 800f88c..1a98eac 100644 --- a/DirectXTex/DirectXTexTGA.cpp +++ b/DirectXTex/DirectXTexTGA.cpp @@ -280,6 +280,12 @@ namespace return HRESULT_E_INVALID_DATA; } + uint64_t sizeBytes = uint64_t(pHeader->wWidth) * uint64_t(pHeader->wHeight) * uint64_t(pHeader->bBitsPerPixel) / 8; + if (sizeBytes > UINT32_MAX) + { + return HRESULT_E_ARITHMETIC_OVERFLOW; + } + metadata.width = pHeader->wWidth; metadata.height = pHeader->wHeight; metadata.depth = metadata.arraySize = metadata.mipLevels = 1; diff --git a/Texconv/PortablePixMap.cpp b/Texconv/PortablePixMap.cpp index 6e07782..faf08b1 100644 --- a/Texconv/PortablePixMap.cpp +++ b/Texconv/PortablePixMap.cpp @@ -157,7 +157,7 @@ HRESULT __cdecl LoadFromPortablePixMap( if (ppmSize < 3) return E_FAIL; - if (ppmData[0] != 'P' || (ppmData[1] != '3' && ppmData[1] != '6')) + if (ppmData[0] != 'P' || (ppmData[1] != '3' && ppmData[1] != '6') || !isspace(ppmData[2])) return E_FAIL; const bool ascii = ppmData[1] == '3'; @@ -280,10 +280,10 @@ HRESULT __cdecl LoadFromPortablePixMap( return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); } - uint64_t sizeBytes = uint64_t(width) * uint64_t(u); + uint64_t sizeBytes = uint64_t(width) * uint64_t(u) * 4; if (sizeBytes > UINT32_MAX) { - HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); } if (metadata) @@ -454,18 +454,19 @@ HRESULT __cdecl LoadFromPortablePixMapHDR( if (pfmSize < 3) return E_FAIL; - if (pfmData[0] != 'P' || pfmData[2] != '\n') + if (pfmData[0] != 'P' || !isspace(pfmData[2])) return E_FAIL; DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; bool monochrome = false; bool half16 = false; + unsigned int bpp = 0; switch (pfmData[1]) { - case 'f': format = DXGI_FORMAT_R32_FLOAT; monochrome = true; break; - case 'F': format = DXGI_FORMAT_R32G32B32A32_FLOAT; break; - case 'h': format = DXGI_FORMAT_R16_FLOAT; monochrome = true; half16 = true; break; - case 'H': format = DXGI_FORMAT_R16G16B16A16_FLOAT; half16 = true; break; + case 'f': format = DXGI_FORMAT_R32_FLOAT; monochrome = true; bpp = 4u; break; + case 'F': format = DXGI_FORMAT_R32G32B32A32_FLOAT; bpp = 16u; break; + case 'h': format = DXGI_FORMAT_R16_FLOAT; monochrome = true; half16 = true; bpp = 2u; break; + case 'H': format = DXGI_FORMAT_R16G16B16A16_FLOAT; half16 = true; bpp = 8u; break; default: return E_FAIL; } @@ -509,10 +510,10 @@ HRESULT __cdecl LoadFromPortablePixMapHDR( return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); } - uint64_t sizeBytes = uint64_t(width) * uint64_t(height); + uint64_t sizeBytes = uint64_t(width) * uint64_t(height) * bpp; if (sizeBytes > UINT32_MAX) { - HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); + return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); } pData += len + 1; diff --git a/build/OneFuzzConfig.json b/build/OneFuzzConfig.json index 30f7272..6de2fca 100644 --- a/build/OneFuzzConfig.json +++ b/build/OneFuzzConfig.json @@ -15,7 +15,10 @@ "TargetName": "DirectXTex", "TargetOptions": [ " -rss_limit_mb=4096" - ] + ], + "TargetEnv": { + "ASAN_OPTIONS": "allocator_may_return_null=1" + } } ], "JobDependencies": [ diff --git a/build/onefuzz-setup.ps1 b/build/onefuzz-setup.ps1 index 55fc44f..7c1c75a 100644 --- a/build/onefuzz-setup.ps1 +++ b/build/onefuzz-setup.ps1 @@ -7,23 +7,6 @@ function Execute-Setup { # Exclude any uploaded DLL from known DLLs gci -filter '*.dll' | Exclude-Library - # Update environment values for ASAN_OPTIONS. - # These environment variables affect how the ASan runtime operates. - # Use the 'allocator_may_return_null=1' environment variable if you have compiled - # your fuzzer using clang with the ASan flags - # - # Use 'windows_hook_rtl_allocators=true:allocator_may_return_null=1' if your fuzzer has - # been compiled using MSVC with the ASan flags - # - # $AsanOptions = 'windows_hook_rtl_allocators=true:allocator_may_return_null=1' - # $AsanOptions = 'allocator_may_return_null=1' - - $AsanOptions = 'windows_hook_rtl_allocators=true:allocator_may_return_null=1' - - # Use the 'machine' scope to make this permanent because the machine will reboot - [Environment]::SetEnvironmentVariable('ASAN_OPTIONS', $AsanOptions, 'Machine') - Write-Log "Set ASAN_OPTIONS to $AsanOptions" - # Done. Useful to know that the script did not prematurely error out Write-Log 'Setup script finished successfully' }