← Advisories

Invalid C++ downcast parsing the DICOM meta-header group length in DCMTK

fixed

Details

Product DCMTK
Vendor OFFIS / Open Connections
Affected through 4ac1337; fixed in 2c8b4288d
CWE CWE-843
Severity low
Status fixed

Timeline

Found 11 Aug 2026
Reported 19 Aug 2026
Fixed 19 Aug 2026
Disclosed 24 Aug 2026

References

Notes

Loading a crafted DICOM file whose File Meta Information Group Length element (0002,0000) is encoded with a value representation other than UL causes DcmMetaInfo::readGroupLength() (dcmdata/libsrc/dcmetinf.cc) to static_cast that element to DcmUnsignedLong * after checking only its tag, never its type. The element the parser actually constructed is a different DcmElement subclass, so the cast is an invalid downcast — undefined behaviour, flagged by UBSan’s vptr check as “downcast of address … which does not point to an object of type ‘DcmUnsignedLong’”. It is reachable from DcmFileFormat::loadFile() on any untrusted .dcm.

Severity is low: getUint32() is virtual, so the call dispatches to the real object’s implementation (which returns an error for a non-numeric element) rather than misinterpreting memory. There is no demonstrated memory-corruption or information-leak consequence — but it is a genuine type-safety defect on attacker-controlled input, and a reasonable hardening fix. A 20-byte PoC reproduces it under a -fsanitize=vptr build.

The bug was found with an AFL++ / ASan+UBSan campaign over the DICOM file parser. DCMTK’s canonical repository is git.dcmtk.org and it routes bug reports through its Redmine tracker rather than GitHub pull requests, so the report went to the project’s bug address. Michael Onken accepted it and fixed it in master commit 2c8b4288d (“Fixed invalid downcast for non-UL group length VR.”), which adds an ident() == EVR_UL guard before the cast — the one-line fix I proposed — and credits glitchfox (Benjamin Ali), closing Redmine #1276.

I rebuilt dcmdata at both the fix commit and its parent under -fsanitize=address,undefined with the vptr check enabled and replayed the PoC. At the parent it trips the invalid-downcast diagnostic at dcmetinf.cc:382; at the fix commit the file is rejected cleanly as corrupted meta information with no sanitizer finding.