GCVE-1988-2026-0438
Vulnerability from gna-1988 – Published: 2026-10-02 04:57 – Updated: 2026-10-02 04:57
VLAI
EPSS
VEX
Title
[SYSS-2026-071]: GDCM (Grassroots DICOM) - Format String (CWE-134)
Summary
Advisory ID: SYSS-2026-071
Product: GDCM (Grassroots DICOM)
Manufacturer: GDCM Project
Affected Version(s): 3.3.0
Tested Version(s): 3.3.0
Vulnerability Type: Format String (CWE-134)
Risk Level: Medium
Solution Status: Open
Manufacturer Notification: 2026-07-24
Public Disclosure: 2026-09-23
CVE Reference: Not yet assigned
Author of Advisory: Matthias Deeg, SySS GmbH
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Overview:
GDCM (Grassroots DICOM) is an open-source C++ library for reading, writing,
and processing DICOM (Digital Imaging and Communications in Medicine)
medical imaging files (see [1]).
The gdcmFilenameGenerator component, used by the gdcmraw command-line tool
to generate output filenames for split fragments, is vulnerable to a
format string vulnerability. The user-supplied pattern string is used
directly as the format string argument to snprintf() without proper
validation of the format specifiers. Only the count of % characters is
checked (exactly one required), but the specifier that follows is not
validated.
An attacker can supply format specifiers such as "%n" to write to arbitrary
memory addresses, or "%s" to dereference small integers as pointers,
causing crashes. Positional parameters like "%5$x" can be used to leak
stack data into generated filenames, enabling information disclosure.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Vulnerability Details:
The vulnerable code is in the FilenameGenerator::Generate() function at
Source/Common/gdcmFilenameGenerator.cxx:94:
int res = snprintf( internal, internal_len, Pattern.c_str(), i );
The Pattern string is set by the user via FilenameGenerator::SetPattern().
In the gdcmraw command-line tool, the pattern comes directly from the
- -p/--pattern command-line argument:
// gdcmraw.cxx:150
pattern = optarg; // user-controlled!
// gdcmraw.cxx:353
fg.SetPattern( pattern.c_str() );
The validation in Generate() only counts % characters and requires
exactly one but does NOT validate what format specifier follows:
const char *pattern = Pattern.c_str();
int num_percent = 0;
while( (pattern = strchr( pattern, '%')) )
{
++pattern;
++num_percent;
}
if ( num_percent != 1 )
{
gdcmDebugMacro( "No more than one % in string formatting please" );
return false;
}
This means patterns like "%s", "%x", "%5$x", and "%n" all pass validation:
- "%s" : treats the loop index i as a char* pointer and attempts to
dereference it, causing a segmentation fault (information
disclosure if the dereferenced memory contains readable data)
- "%x" : reads the loop index value as hex and embeds it in the filename
- "%5$x": positional parameter that skips past the provided argument
to the 5th variadic argument on the stack, leaking arbitrary
stack data into the generated filename (information disclosure)
- "%n" : interprets the loop index i as an int* and writes the number
of bytes written so far to that address, enabling arbitrary
memory writes and potential remote code execution
The loop index i is of type SizeType (unsigned long / size_t). When
interpreted as a pointer, small index values (0, 1, 2, ...) point to
invalid memory addresses, causing immediate segmentation faults. The
"%n" specifier is particularly dangerous as it enables write-what-where
attacks if the attacker can control the stack layout.
The exploitability of the vulnerable code with the different shown
options depends on on the used compiler settings, for example glibc's
FORTIFY_SOURCE.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Proof of Concept (PoC):
Using the format specifier "%s" in combination with a multi-fragment
DICOM file leads to a segmentation fault as the loop index gets interpreted
as char* pointer. When the loop counter is 1, snprintft() attempts to
read from address 0x1.
gdcmraw -i multifrag.dcm -o output_ --split-frags -p '%s'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Solution:
SySS GmbH is not aware of a security update for the described issue.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Disclosure Timeline:
2026-07-24: Vulnerability reported to manufacturer
2026-07-31: Vulnerability reported to manufacturer again
2026-09-23: Public release of security advisory
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
References:
[1] GDCM project website
https://gdcm.sourceforge.net/
[2] SySS Security Advisory SYSS-2026-071
[3] SySS GmbH, SySS Responsible Disclosure Policy
https://www.syss.de/en/responsible-disclosure-policy
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Credits:
This security vulnerability was found by Matthias Deeg of SySS GmbH with
the assistance of SySS AI.
E-Mail: matthias.deeg (at) syss.de
Key fingerprint = D1F0 A035 F06C E675 CDB9 0514 D9A4 BF6A 34AD 4DAB
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Disclaimer:
The information provided in this security advisory is provided "as is"
and without warranty of any kind. Details of this security advisory may
be updated in order to provide as accurate information as possible. The
latest version of this security advisory is available on the SySS website.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Copyright:
Creative Commons - Attribution (by) - Version 4.0
URL: https://creativecommons.org/licenses/by/4.0/deed.en
_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: https://seclists.org/fulldisclosure/
Severity
No CVSS data available.
CWE
Assigner
References
7 references
Impacted products
1 product
| Vendor | Product | Version | CPE status | |
|---|---|---|---|---|
| unknown | GDCM (Grassroots DICOM) |
Affected:
unknown
|
guessed |
{
"containers": {
"cna": {
"affected": [
{
"product": "GDCM (Grassroots DICOM)",
"vendor": "unknown",
"versions": [
{
"status": "affected",
"version": "unknown"
}
]
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Matthias Deeg via Fulldisclosure"
}
],
"descriptions": [
{
"lang": "en",
"value": "Advisory ID: SYSS-2026-071\nProduct: GDCM (Grassroots DICOM)\nManufacturer: GDCM Project\nAffected Version(s): 3.3.0\nTested Version(s): 3.3.0\nVulnerability Type: Format String (CWE-134)\nRisk Level: Medium\nSolution Status: Open\nManufacturer Notification: 2026-07-24\nPublic Disclosure: 2026-09-23\nCVE Reference: Not yet assigned\nAuthor of Advisory: Matthias Deeg, SySS GmbH\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nOverview:\n\nGDCM (Grassroots DICOM) is an open-source C++ library for reading, writing,\nand processing DICOM (Digital Imaging and Communications in Medicine)\nmedical imaging files (see [1]).\n\nThe gdcmFilenameGenerator component, used by the gdcmraw command-line tool\nto generate output filenames for split fragments, is vulnerable to a\nformat string vulnerability. The user-supplied pattern string is used\ndirectly as the format string argument to snprintf() without proper\nvalidation of the format specifiers. Only the count of % characters is\nchecked (exactly one required), but the specifier that follows is not\nvalidated.\n\nAn attacker can supply format specifiers such as \"%n\" to write to arbitrary\nmemory addresses, or \"%s\" to dereference small integers as pointers,\ncausing crashes. Positional parameters like \"%5$x\" can be used to leak\nstack data into generated filenames, enabling information disclosure.\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nVulnerability Details:\n\nThe vulnerable code is in the FilenameGenerator::Generate() function at\nSource/Common/gdcmFilenameGenerator.cxx:94:\n\n int res = snprintf( internal, internal_len, Pattern.c_str(), i );\n\nThe Pattern string is set by the user via FilenameGenerator::SetPattern().\nIn the gdcmraw command-line tool, the pattern comes directly from the\n- -p/--pattern command-line argument:\n\n // gdcmraw.cxx:150\n pattern = optarg; // user-controlled!\n // gdcmraw.cxx:353\n fg.SetPattern( pattern.c_str() );\n\nThe validation in Generate() only counts % characters and requires\nexactly one but does NOT validate what format specifier follows:\n\n const char *pattern = Pattern.c_str();\n int num_percent = 0;\n while( (pattern = strchr( pattern, \u0027%\u0027)) )\n {\n ++pattern;\n ++num_percent;\n }\n if ( num_percent != 1 )\n {\n gdcmDebugMacro( \"No more than one % in string formatting please\" );\n return false;\n }\n\nThis means patterns like \"%s\", \"%x\", \"%5$x\", and \"%n\" all pass validation:\n\n - \"%s\" : treats the loop index i as a char* pointer and attempts to\n dereference it, causing a segmentation fault (information\n disclosure if the dereferenced memory contains readable data)\n - \"%x\" : reads the loop index value as hex and embeds it in the filename\n - \"%5$x\": positional parameter that skips past the provided argument\n to the 5th variadic argument on the stack, leaking arbitrary\n stack data into the generated filename (information disclosure)\n - \"%n\" : interprets the loop index i as an int* and writes the number\n of bytes written so far to that address, enabling arbitrary\n memory writes and potential remote code execution\n\nThe loop index i is of type SizeType (unsigned long / size_t). When\ninterpreted as a pointer, small index values (0, 1, 2, ...) point to\ninvalid memory addresses, causing immediate segmentation faults. The\n\"%n\" specifier is particularly dangerous as it enables write-what-where\nattacks if the attacker can control the stack layout.\n\nThe exploitability of the vulnerable code with the different shown\noptions depends on on the used compiler settings, for example glibc\u0027s\nFORTIFY_SOURCE.\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nProof of Concept (PoC):\n\nUsing the format specifier \"%s\" in combination with a multi-fragment\nDICOM file leads to a segmentation fault as the loop index gets interpreted\nas char* pointer. When the loop counter is 1, snprintft() attempts to\nread from address 0x1.\n\ngdcmraw -i multifrag.dcm -o output_ --split-frags -p \u0027%s\u0027\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSolution:\n\nSySS GmbH is not aware of a security update for the described issue.\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nDisclosure Timeline:\n\n2026-07-24: Vulnerability reported to manufacturer\n2026-07-31: Vulnerability reported to manufacturer again\n2026-09-23: Public release of security advisory\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nReferences:\n\n[1] GDCM project website\n https://gdcm.sourceforge.net/\n[2] SySS Security Advisory SYSS-2026-071\n\n[3] SySS GmbH, SySS Responsible Disclosure Policy\n https://www.syss.de/en/responsible-disclosure-policy\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nCredits:\n\nThis security vulnerability was found by Matthias Deeg of SySS GmbH with\nthe assistance of SySS AI.\n\nE-Mail: matthias.deeg (at) syss.de\n\nKey fingerprint = D1F0 A035 F06C E675 CDB9 0514 D9A4 BF6A 34AD 4DAB\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nDisclaimer:\n\nThe information provided in this security advisory is provided \"as is\"\nand without warranty of any kind. Details of this security advisory may\nbe updated in order to provide as accurate information as possible. The\nlatest version of this security advisory is available on the SySS website.\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nCopyright:\n\nCreative Commons - Attribution (by) - Version 4.0\nURL: https://creativecommons.org/licenses/by/4.0/deed.en\n\n_______________________________________________\nSent through the Full Disclosure mailing list\nhttps://nmap.org/mailman/listinfo/fulldisclosure\nWeb Archives \u0026 RSS: https://seclists.org/fulldisclosure/"
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-134",
"description": "CWE-134",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-10-02T04:57:34Z",
"orgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
"shortName": "VULNARCHIVE"
},
"references": [
{
"tags": [
"technical-description",
"exploit"
],
"url": "https://vuln.freearchive.org/archive/full-disclosure/2026/Sep/87"
},
{
"tags": [
"technical-description"
],
"url": "https://seclists.org/fulldisclosure/2026/Sep/87"
},
{
"url": "https://creativecommons.org/licenses/by/4.0/deed.en"
},
{
"url": "https://gdcm.sourceforge.net/"
},
{
"url": "https://nmap.org/mailman/listinfo/fulldisclosure"
},
{
"url": "https://seclists.org/fulldisclosure/"
},
{
"url": "https://www.syss.de/en/responsible-disclosure-policy"
}
],
"source": {
"defect": [
"https://seclists.org/fulldisclosure/2026/Sep/87"
],
"discovery": "EXTERNAL"
},
"title": "[SYSS-2026-071]: GDCM (Grassroots DICOM) - Format String (CWE-134)",
"x_gcve": [
{
"recordType": "advisory",
"relationships": [],
"vulnId": "GCVE-1988-2026-0438",
"x_vulnarchive": {
"archiveUrl": "https://vuln.freearchive.org/archive/full-disclosure/2026/Sep/87",
"automated": true,
"contentSha256": "90c70433a3314393c67116213041c17b14b3ce8295b1d13c8e081ac5dca3a95e",
"evidenceScore": 10,
"messageId": "",
"originalUrl": "https://seclists.org/fulldisclosure/2026/Sep/87",
"policy": "vulnarchive-1",
"sourceFormat": "text/html",
"sourcePublishedAt": "2026-09-23T13:33:50Z"
}
}
]
}
},
"cveMetadata": {
"assignerOrgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
"assignerShortName": "VULNARCHIVE",
"datePublished": "2026-10-02T04:57:34Z",
"dateUpdated": "2026-10-02T04:57:34Z",
"state": "PUBLISHED",
"vulnId": "GCVE-1988-2026-0438"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
Loading…
Loading…
Experimental. This forecast is provided for visualization only and may change without notice. Do not use it for operational decisions.
Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Loading…
Loading…
The MITRE ATT&CK techniques below are AI-generated suggestions, inferred from the description of the
vulnerability by the CIRCL/vulnerability-attack-technique-classification-roberta-base
model, served locally by ML-Gateway.
They have not been verified by an analyst and are provided for guidance only.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Loading…
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.
Loading…