GCVE-1988-2026-0436

Vulnerability from gna-1988 – Published: 2026-10-02 04:57 – Updated: 2026-10-02 04:57
VLAI
Title
[SYSS-2026-069]: GDCM (Grassroots DICOM) - Integer Overflow (CWE-190)
Summary
Advisory ID: SYSS-2026-069 Product: GDCM (Grassroots DICOM) Manufacturer: GDCM Project Affected Version(s): 3.3.0 Tested Version(s): 3.3.0 Vulnerability Type: Integer Overflow (CWE-190) Risk Level: High 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 JPEG2000 image codec in GDCM, used for decoding JPEG2000-compressed DICOM pixel data, is vulnerable to an integer overflow that leads to a heap buffer overflow. The buffer size for decoded pixel data is computed using 32-bit unsigned integer arithmetic based on image dimensions (rows * columns) from the DICOM header. When the product exceeds 2^32, the result silently wraps around, causing an undersized buffer allocation. The subsequent pixel data write loop then overflows the heap buffer. A malicious DICOM file with crafted image dimensions can trigger this vulnerability, potentially leading to remote code execution in the context of the user processing the file. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Vulnerability Details: The vulnerable code is in the JPEG2000Codec::DecodeCommon function at Source/MediaStorageAndFileFormat/gdcmJPEG2000Codec.cxx:1037-1038: unsigned long len = Dimensions[0]*Dimensions[1] * (PF.GetBitsAllocated() / 8) * image->numcomps; char *raw = new char[len]; The variables Dimensions[0] and Dimensions[1] are both 'unsigned int' (32-bit) values inherited from the ImageCodec base class, populated from the DICOM header's Rows and Columns elements (VR=US, maximum value 65535). The multiplication chain Dimensions[0]*Dimensions[1]*(PF.GetBitsAllocated()/8)*image->numcomps is executed entirely in 32-bit unsigned integer arithmetic, because all operands are 32-bit types. The result is only widened to 'unsigned long' on assignment to 'len', after the overflow has already occurred. When the product exceeds 2^32, it wraps around modulo 2^32. Following the allocation, the decoded pixel data is written to the 'raw' buffer in a loop: for (int i = 0; i < wr * hr; i++) { int v = image->comps[compno].data[i / wr * w + i % wr]; *data8 = (uint8_t)v; data8 += image->numcomps; } This loop writes wr*hr pixels, each advancing the pointer by numcomps, to the 'raw' buffer. Since the buffer is far smaller than needed due to the integer overflow, this write operation causes a heap buffer overflow. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Proof of Concept (PoC): A PoC was developed that reproduces the vulnerable calculation and buffer allocation pattern from gdcmJPEG2000Codec.cxx, simulating the pixel data write loop that overflows the undersized buffer. PoC source code: #include <cstdint> #include <cstdio> #include <cstring> typedef unsigned int uint32; typedef unsigned long ulong; static void vulnerable_jpeg2000_decode(uint32 dim_x, uint32 dim_y, int bits_allocated, int numcomps) { // Vulnerable calculation (gdcmJPEG2000Codec.cxx:1037) unsigned long len = dim_x * dim_y * (bits_allocated / 8) * numcomps; // Vulnerable allocation (gdcmJPEG2000Codec.cxx:1038) char *raw = new char[len]; unsigned long actual_bytes = (unsigned long long)dim_x * dim_y * (bits_allocated / 8) * numcomps; // Vulnerable pixel write loop (gdcmJPEG2000Codec.cxx:1084-1092) for (unsigned long i = 0; i < actual_bytes; i++) { raw[i] = (char)(i & 0xFF); } delete[] raw; } int main() { // Test Case 1: 16-bit grayscale, 65536 x 65536 // Product overflows to 0, buffer allocated as 0 bytes vulnerable_jpeg2000_decode(65536, 65536, 16, 1); return 0; } To build and run the PoC: g++ -fsanitize=address -fno-omit-frame-pointer -g \ pocs/poc_jpeg2000_integer_overflow.cpp -o poc Running the PoC triggers the heap buffer overflow, detected by ASan: $ ./poc ==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7b2dac5e0010 at pc 0x557e499c4371 bp 0x7ffdf03c63a0 sp 0x7ffdf03c6390 WRITE of size 1 at 0x7b2dac5e0010 thread T0 #0 0x557e499c4370 in vulnerable_jpeg2000_decode poc_jpeg2000_integer_overflow.cpp:106 #1 0x557e499c442d in main poc_jpeg2000_integer_overflow.cpp:131 0x7b2dac5e0010 is located 0 bytes inside of 1-byte region [0x7b2dac5e0010,0x7b2dac5e0011) allocated by thread T0 here: #0 0x7f0dadd2d431 in operator new[](unsigned long) #1 0x557e499c420e in vulnerable_jpeg2000_decode poc_jpeg2000_integer_overflow.cpp:79 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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-069 [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
Impacted products
Vendor Product Version CPE status
unknown GDCM (Grassroots DICOM) Affected: unknown
guessed Create a notification for this product.

{
  "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-069\nProduct:                   GDCM (Grassroots DICOM)\nManufacturer:              GDCM Project\nAffected Version(s):       3.3.0\nTested Version(s):         3.3.0\nVulnerability Type:        Integer Overflow (CWE-190)\nRisk Level:                High\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 JPEG2000 image codec in GDCM, used for decoding JPEG2000-compressed\nDICOM pixel data, is vulnerable to an integer overflow that leads to a\nheap buffer overflow. The buffer size for decoded pixel data is computed\nusing 32-bit unsigned integer arithmetic based on image dimensions\n(rows * columns) from the DICOM header. When the product exceeds 2^32,\nthe result silently wraps around, causing an undersized buffer allocation.\nThe subsequent pixel data write loop then overflows the heap buffer.\nA malicious DICOM file with crafted image dimensions can trigger this\nvulnerability, potentially leading to remote code execution in the\ncontext of the user processing the file.\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nVulnerability Details:\n\nThe vulnerable code is in the JPEG2000Codec::DecodeCommon function at\nSource/MediaStorageAndFileFormat/gdcmJPEG2000Codec.cxx:1037-1038:\n\n  unsigned long len = Dimensions[0]*Dimensions[1] *\n                      (PF.GetBitsAllocated() / 8) * image-\u003enumcomps;\n  char *raw = new char[len];\n\nThe variables Dimensions[0] and Dimensions[1] are both \u0027unsigned int\u0027\n(32-bit) values inherited from the ImageCodec base class, populated from\nthe DICOM header\u0027s Rows and Columns elements (VR=US, maximum value\n65535). The multiplication chain\nDimensions[0]*Dimensions[1]*(PF.GetBitsAllocated()/8)*image-\u003enumcomps\nis executed entirely in 32-bit unsigned integer arithmetic, because all\noperands are 32-bit types. The result is only widened to \u0027unsigned long\u0027\non assignment to \u0027len\u0027, after the overflow has already occurred.\n\nWhen the product exceeds 2^32, it wraps around modulo 2^32.\n\nFollowing the allocation, the decoded pixel data is written to the \u0027raw\u0027\nbuffer in a loop:\n\n  for (int i = 0; i \u003c wr * hr; i++) {\n      int v = image-\u003ecomps[compno].data[i / wr * w + i % wr];\n      *data8 = (uint8_t)v;\n      data8 += image-\u003enumcomps;\n  }\n\nThis loop writes wr*hr pixels, each advancing the pointer by numcomps,\nto the \u0027raw\u0027 buffer. Since the buffer is far smaller than needed due to\nthe integer overflow, this write operation causes a heap buffer overflow.\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nProof of Concept (PoC):\n\nA PoC was developed that reproduces the vulnerable calculation and\nbuffer allocation pattern from gdcmJPEG2000Codec.cxx, simulating the\npixel data write loop that overflows the undersized buffer.\n\nPoC source code:\n\n#include \u003ccstdint\u003e\n#include \u003ccstdio\u003e\n#include \u003ccstring\u003e\n\ntypedef unsigned int uint32;\ntypedef unsigned long ulong;\n\nstatic void vulnerable_jpeg2000_decode(uint32 dim_x, uint32 dim_y,\n                                       int bits_allocated, int numcomps)\n{\n    // Vulnerable calculation (gdcmJPEG2000Codec.cxx:1037)\n    unsigned long len = dim_x * dim_y *\n                        (bits_allocated / 8) * numcomps;\n\n    // Vulnerable allocation (gdcmJPEG2000Codec.cxx:1038)\n    char *raw = new char[len];\n\n    unsigned long actual_bytes = (unsigned long long)dim_x * dim_y *\n                                 (bits_allocated / 8) * numcomps;\n\n    // Vulnerable pixel write loop (gdcmJPEG2000Codec.cxx:1084-1092)\n    for (unsigned long i = 0; i \u003c actual_bytes; i++) {\n        raw[i] = (char)(i \u0026 0xFF);\n    }\n\n    delete[] raw;\n}\n\nint main()\n{\n    // Test Case 1: 16-bit grayscale, 65536 x 65536\n    // Product overflows to 0, buffer allocated as 0 bytes\n    vulnerable_jpeg2000_decode(65536, 65536, 16, 1);\n    return 0;\n}\n\nTo build and run the PoC:\n\ng++ -fsanitize=address -fno-omit-frame-pointer -g \\\n  pocs/poc_jpeg2000_integer_overflow.cpp -o poc\n\nRunning the PoC triggers the heap buffer overflow, detected by ASan:\n\n  $ ./poc\n  ==ERROR: AddressSanitizer: heap-buffer-overflow on address\n  0x7b2dac5e0010 at pc 0x557e499c4371 bp 0x7ffdf03c63a0 sp 0x7ffdf03c6390\n  WRITE of size 1 at 0x7b2dac5e0010 thread T0\n      #0 0x557e499c4370 in vulnerable_jpeg2000_decode\n          poc_jpeg2000_integer_overflow.cpp:106\n      #1 0x557e499c442d in main\n          poc_jpeg2000_integer_overflow.cpp:131\n  0x7b2dac5e0010 is located 0 bytes inside of 1-byte region\n  [0x7b2dac5e0010,0x7b2dac5e0011) allocated by thread T0 here:\n      #0 0x7f0dadd2d431 in operator new[](unsigned long)\n      #1 0x557e499c420e in vulnerable_jpeg2000_decode\n          poc_jpeg2000_integer_overflow.cpp:79\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-069\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\nwebsite.\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-190",
              "description": "CWE-190",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-10-02T04:57:33Z",
        "orgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
        "shortName": "VULNARCHIVE"
      },
      "references": [
        {
          "tags": [
            "technical-description",
            "exploit"
          ],
          "url": "https://vuln.freearchive.org/archive/full-disclosure/2026/Sep/85"
        },
        {
          "tags": [
            "technical-description"
          ],
          "url": "https://seclists.org/fulldisclosure/2026/Sep/85"
        },
        {
          "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/85"
        ],
        "discovery": "EXTERNAL"
      },
      "title": "[SYSS-2026-069]: GDCM (Grassroots DICOM) - Integer Overflow (CWE-190)",
      "x_gcve": [
        {
          "recordType": "advisory",
          "relationships": [],
          "vulnId": "GCVE-1988-2026-0436",
          "x_vulnarchive": {
            "archiveUrl": "https://vuln.freearchive.org/archive/full-disclosure/2026/Sep/85",
            "automated": true,
            "contentSha256": "baf48fec3d1cbb79cfc98a855bc463d14707520aab4f578cab6023a5ce49d434",
            "evidenceScore": 10,
            "messageId": "",
            "originalUrl": "https://seclists.org/fulldisclosure/2026/Sep/85",
            "policy": "vulnarchive-1",
            "sourceFormat": "text/html",
            "sourcePublishedAt": "2026-09-23T13:33:39Z"
          }
        }
      ]
    }
  },
  "cveMetadata": {
    "assignerOrgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
    "assignerShortName": "VULNARCHIVE",
    "datePublished": "2026-10-02T04:57:33Z",
    "dateUpdated": "2026-10-02T04:57:33Z",
    "state": "PUBLISHED",
    "vulnId": "GCVE-1988-2026-0436"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

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…

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…