Mercurial > hg > orthanc
changeset 6646:f1140bd7ed65 machine-spirits
Fix possible overflow when calling /tools/create-dicom with a PAM file
| author | Alain Mazy <am@orthanc.team> |
|---|---|
| date | Tue, 03 Mar 2026 16:04:54 +0100 |
| parents | b8e78ccac532 |
| children | 983a74f5b875 |
| files | NEWS OrthancFramework/Sources/Images/PamReader.cpp |
| diffstat | 2 files changed, 21 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Fri Mar 20 09:32:16 2026 +0100 +++ b/NEWS Tue Mar 03 16:04:54 2026 +0100 @@ -143,6 +143,7 @@ - Avoid adding twice the same tag in DB for the same resource, e.g. when "TimeZoneOffsetFromUTC" is added to the "ExtraMainDicomTags" at Patient level. https://discourse.orthanc-server.org/t/jobs-api-the-dicommovescu-job-doesnt-seems-to-track-progress/3140/14 + - Fix possible overflow when calling /tools/create-dicom with a PAM file. * Upgraded dependencies for static builds: - civetweb 1.16, including patch for CVE-2025-55763 - SQLite 3.50.4
--- a/OrthancFramework/Sources/Images/PamReader.cpp Fri Mar 20 09:32:16 2026 +0100 +++ b/OrthancFramework/Sources/Images/PamReader.cpp Tue Mar 03 16:04:54 2026 +0100 @@ -38,6 +38,7 @@ #include <boost/algorithm/string/find.hpp> #include <boost/lexical_cast.hpp> +static const uint64_t MAX_PAM_IMAGE_BUFFER_SIZE = 4ul * 1024ul * 1024ul * 1024ul; namespace Orthanc { @@ -181,11 +182,28 @@ const unsigned int maxValue = LookupIntegerParameter(parameters, "MAXVAL"); const std::string tupleType = LookupStringParameter(parameters, "TUPLTYPE"); + if (width > 65535 || height > 65535 || channelCount > 4 || maxValue > 65535) + { + throw OrthancException(ErrorCode_BadFileFormat, "PAM header values exceed reasonable limits"); + } + unsigned int bytesPerChannel; PixelFormat format; GetPixelFormat(format, bytesPerChannel, maxValue, channelCount, tupleType); - unsigned int pitch = width * channelCount * bytesPerChannel; + // unsigned int pitch = width * channelCount * bytesPerChannel; + uint64_t pitch = static_cast<uint64_t>(width) * channelCount * bytesPerChannel; + + if (pitch > std::numeric_limits<unsigned int>::max()) + { + throw OrthancException(ErrorCode_BadFileFormat, "PAM dimensions exceed limits"); + } + + uint64_t totalSize = pitch * height; + if (totalSize > MAX_PAM_IMAGE_BUFFER_SIZE) + { + throw OrthancException(ErrorCode_BadFileFormat, "PAM image too large"); + } if (content_.size() != header.size() + headerDelimiter.size() + pitch * height) { @@ -196,7 +214,7 @@ { intptr_t bufferAddr = reinterpret_cast<intptr_t>(&content_[offset]); - if((bufferAddr % 8) == 0) + if ((bufferAddr % 8) == 0) LOG(TRACE) << "PamReader::ParseContent() image address = " << bufferAddr; else LOG(TRACE) << "PamReader::ParseContent() image address = " << bufferAddr << " (not a multiple of 8!)";
