# HG changeset patch # User Alain Mazy # Date 1772550294 -3600 # Node ID f1140bd7ed6516e40916c98a0cdaa5613423c9ef # Parent b8e78ccac53255281d385cdc34f661acb67dd186 Fix possible overflow when calling /tools/create-dicom with a PAM file diff -r b8e78ccac532 -r f1140bd7ed65 NEWS --- 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 diff -r b8e78ccac532 -r f1140bd7ed65 OrthancFramework/Sources/Images/PamReader.cpp --- 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 #include +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(width) * channelCount * bytesPerChannel; + + if (pitch > std::numeric_limits::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(&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!)";