Bug #1189 » IC-DCMTK-0002_REPORT.md
IC-DCMTK-0002: Double-Free in DcmJSONReader via decodeBase64()
Version: DCMTK master 418274445 (DCMTK-3.7.0+64)
CWE: CWE-415 (Double Free)
Description
DcmJSONReader::parseElement() at dcjsonrd.cc:744-752 calls OFStandard::decodeBase64() to decode an inlineBinary field. When the base64 input is invalid (fewer than 4 characters), decodeBase64() frees the output buffer at ofstd.cc:1892 but does not nullify the caller's pointer. parseElement() then unconditionally executes delete[] data at line 752, causing a double-free.
// ofstd.cc:1892 — first free
if (count == 0)
{
delete[] result; // frees buffer, but result NOT set to NULL
}
return count; // returns 0
// dcjsonrd.cc:744-752 — second free
const size_t length = OFStandard::decodeBase64(value, data);
if (length > 0)
result = storeInlineBinaryValue(*newElem, data, length);
delete[] data; // DOUBLE FREE — data already freed above
Reproduction
echo '{"7FE00010":{"vr":"OB","inlinebinary":"A"}}' > poc.json
json2dcm poc.json /dev/null
Actual output:
=================================================================
==2185581==ERROR: AddressSanitizer: attempting double-free on 0x7c1ff6fcc990 in thread T0:
#0 0x55555570cb1d in operator delete[](void*) (build-asan/bin/json2dcm+0x1b8b1d)
#1 0x5555557931bf in DcmJSONReader::parseElement(DcmItem*, DcmItem*, jsmntok*&) dcmdata/libsrc/dcjsonrd.cc:752:9
#2 0x555555797e03 in DcmJSONReader::parseDataSet(DcmItem*, DcmItem*, jsmntok*&) dcmdata/libsrc/dcjsonrd.cc:923:18
#3 0x5555557a19c7 in DcmJSONReader::readAndConvertJSONFile(DcmFileFormat&, char const*) dcmdata/libsrc/dcjsonrd.cc:1279:18
#4 0x55555571339b in main dcmdata/apps/json2dcm.cc:435:25
#5 0x7ffff7989082 in __libc_start_main /build/glibc-LcI20x/glibc-2.31/csu/../csu/libc-start.c:308:16
0x7c1ff6fcc990 is located 0 bytes inside of 3-byte region [0x7c1ff6fcc990,0x7c1ff6fcc993)
freed by thread T0 here:
#0 0x55555570cb1d in operator delete[](void*) (build-asan/bin/json2dcm+0x1b8b1d)
#1 0x555555986ac2 in OFStandard::decodeBase64(OFString const&, unsigned char*&) ofstd/libsrc/ofstd.cc:1892:17
#2 0x555555792cce in DcmJSONReader::parseElement(DcmItem*, DcmItem*, jsmntok*&) dcmdata/libsrc/dcjsonrd.cc:746:31
#3 0x555555797e03 in DcmJSONReader::parseDataSet(DcmItem*, DcmItem*, jsmntok*&) dcmdata/libsrc/dcjsonrd.cc:923:18
#4 0x5555557a19c7 in DcmJSONReader::readAndConvertJSONFile(DcmFileFormat&, char const*) dcmdata/libsrc/dcjsonrd.cc:1279:18
#5 0x55555571339b in main dcmdata/apps/json2dcm.cc:435:25
previously allocated by thread T0 here:
#0 0x55555570c2cd in operator new[](unsigned long) (build-asan/bin/json2dcm+0x1b82cd)
#1 0x5555559860b6 in OFStandard::decodeBase64(OFString const&, unsigned char*&) ofstd/libsrc/ofstd.cc:1847:18
#2 0x555555792cce in DcmJSONReader::parseElement(DcmItem*, DcmItem*, jsmntok*&) dcmdata/libsrc/dcjsonrd.cc:746:31
#3 0x555555797e03 in DcmJSONReader::parseDataSet(DcmItem*, DcmItem*, jsmntok*&) dcmdata/libsrc/dcjsonrd.cc:923:18
#4 0x5555557a19c7 in DcmJSONReader::readAndConvertJSONFile(DcmFileFormat&, char const*) dcmdata/libsrc/dcjsonrd.cc:1279:18
#5 0x55555571339b in main dcmdata/apps/json2dcm.cc:435:25
SUMMARY: AddressSanitizer: double-free (build-asan/bin/json2dcm+0x1b8b1d) in operator delete[](void*)
==2185581==ABORTING
Fix
Nullify the pointer after freeing to prevent the caller's unconditional delete[] from causing a double-free:
// ofstd.cc:1892
if (count == 0)
{
delete[] result;
result = NULL;
}
- « Previous
- 1
- 2
- 3
- Next »