|
|
Message-ID: <CAK3hNHbTxS9nfAgpcX+3+_i_cYfDWxxcgyJiqBBdz7JJqTA6Mg@mail.gmail.com> Date: Wed, 9 Sep 2026 19:17:07 -0700 From: Abhinav Agarwal <abhinavagarwal1996@...il.com> To: oss-security@...ts.openwall.com Subject: GDCM <= 3.2.7: six memory-safety and denial-of-service vulnerabilities, no CVE I am disclosing six vulnerabilities in GDCM (Grassroots DICOM), an open-source C++ library for parsing and processing DICOM files. I confirmed all six against GDCM 3.2.6 with AddressSanitizer or UndefinedBehaviorSanitizer; source review found the vulnerable patterns through 3.2.7 and in the reviewed upstream master snapshot. Impact includes heap corruption, process-memory disclosure, stack exhaustion, and process termination when an application parses, decodes, or transcodes a crafted DICOM file. Affected: per-finding ranges below, all through v3.2.7 Fix status: no fix CVE: not assigned CVSS: researcher-assigned v3.1 scores Findings -------- 1. RLE + YBR_FULL_422 multi-frame decode heap overflow - v3.0.4 through v3.2.7 - CWE-787 - CVSS v3.1 9.8. RLECodec::DecodeFragment() copies the expanded decoded frame into a fixed per-frame slot without checking that the expanded size still fits. YBR_FULL_422 conversion makes a crafted two-frame image exceed that slot; ASan reports a 36,864-byte write immediately after a 24,576-byte allocation. The overflow gives controlled adjacent bytes in an instrumented layout. On the tested unmodified glibc layout it corrupts a freed chunk and reliably aborts; no code-execution path was found there. 2. JPEG2000 small-image encode heap overflow - v2.0.16 through v3.2.7 - CWE-787 - CVSS v3.1 9.8. JPEG2000Codec::CodeFrameIntoBuffer() allocates inputlength*2 bytes, but the OpenJPEG memory callback copies the complete codestream without enforcing that limit. A 2x2 8-bit image provides four input bytes and an eight-byte output allocation, while OpenJPEG emits at least 132 bytes. ASan confirms the resulting heap overwrite through both gdcmconv --j2k and the ImageChangeTransferSyntax API used by applications for transcoding. Impact is process crash or adjacent heap corruption during encode/transcode. 3. Segmented palette color out-of-bounds heap read - v2.0.5 through v3.2.7 - CWE-125 - CVSS v3.1 8.2. DiscreteSegment trusts the segment's attacker-controlled uint16 entry count when calculating its end, and std::copy reads past the actual LUT element allocation. The maximum tested overread is 131,070 bytes. Out-of-bounds words reach the decoded RGB pixel buffer; on the tested Linux build they included a gdcm::ByteValue vtable pointer from which the correct libgdcmDSED load base was derived in six ASLR-enabled runs. Impact is process-memory disclosure to a caller that obtains the decoded pixels, plus possible crash on an unmapped read. 4. JPEG2000 BitsAllocated precision mismatch - v2.0.8 through v3.2.7 - CWE-787 - CVSS v3.1 8.1. DecodeByStreamsCommon() allocates its raw buffer from the DICOM BitsAllocated value, then selects a wider output loop from the JPEG2000 component precision. The dimension-only CVE-2024-22373 fix does not validate that precision, and the relevant assertion is compiled out with GDCM's default GDCM_SUPPORT_BROKEN_IMPLEMENTATION=ON configuration. A file declaring BitsAllocated=8 with a 31-bit JPEG2000 component causes a four-times-wider write; ASan reports 12,288 bytes written past a 4,096-byte allocation through ImageRegionReader::ReadIntoBuffer(). Impact is heap corruption in applications using this region/ROI decode API. 5. Unbounded DICOM sequence recursion - v2.0.4 or earlier through v3.2.7 - CWE-674 - CVSS v3.1 7.5. DataSet::ReadNested(), Item::Read(), and SequenceOfItems::Read() recursively parse nested SQ items without a depth limit. A 528 KiB file containing 15,000 nested Content Sequence items exhausts the thread stack during Reader::Read(); ASan reports stack overflow and gdcmdump also terminates. Impact is unauthenticated denial of service wherever an untrusted DICOM file reaches ordinary dataset parsing. 6. RLE NumSegments=0 divide by zero - v2.0.4 or earlier through v3.2.7 - CWE-369 - CVSS v3.1 7.5. RLEHeader::SetNumSegments() rejects values above 15 but accepts zero, which later reaches length /= numSegments in the RLE decode path. The crafted file produces a UBSan division-by-zero report; x86-64 raises SIGFPE, while the tested ARM64 path reaches an assertion and abort. Impact is process termination during ordinary RLE image parsing. Proof of concept ---------------- The public repository contains deterministic DICOM generators, fixtures, minimal harnesses, matched controls, build instructions, sanitizer expectations, and retained Linux/macOS evidence: https://github.com/abhinavagarwal07/gdcm-security-poc Orthanc deployments using the optional GDCM plugin are likely affected where these codec paths are reached, but I have not proven end-to-end exploitability in Orthanc. Coordination timeline --------------------- 2026-05-11 Contacted a GDCM maintainer and developers list seeking a private reporting channel; no maintainer response. 2026-05-15 Reported all six findings to CISA through VINCE as VU#617940. 2026-05-28 to 2026-06-12 CISA's contact attempts also received no response, and it began its unresponsive-vendor process. 2026-06-14 Supplied full technical details, affected versions, impacts, CVSS/CWE data, and reproduction material. 2026-07-09 Initial VINCE disclosure date passed while CISA continued validation. 2026-07-14 to 2026-07-22 Supplied packaged PoCs, binaries, build instructions, and additional reproduction guidance at CISA's request. 2026-07-30 CISA said testing was ongoing and verified findings would receive CVEs and an advisory. 2026-08-17 to 2026-08-18 Requested permission to disclose after more than 90 days; agreed to CISA's request for another two-week hold through September 1. 2026-09-01 to 2026-09-08 Continued follow-ups after the extended date passed. 2026-09-09 CISA said I was free to publish and closed the case pending evidence of a concrete third-party attack path, with the option to reopen it and assign CVEs later. 2026-09-09 Public disclosure, 122 days after initial maintainer contact and 118 days after reporting to CISA. I withheld technical disclosure throughout coordination, provided the requested reproduction material, and extended the embargo at CISA's request. Mitigation ---------- Until fixes are available, avoid processing untrusted DICOM files, disable unnecessary decoding/transcoding paths, and restrict DICOM services to trusted networks. Credit ------ Reported by Abhinav Agarwal.
Powered by blists - more mailing lists
Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.