Search

Find a vulnerability

Search criteria

    2 vulnerabilities by silviucpp

    CVE-2026-119434 (GCVE-0-2026-119434)

    Vulnerability from nvd – Published: 2026-11-05 20:15 – Updated: 2026-11-05 20:45
    VLAI
    Title
    Decompression bomb in ezstd:decompress_using_ddict/2 allows BEAM memory exhaustion via unbounded output buffer
    Summary
    Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to ezstd:decompress_using_ddict/2 to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size. zstd_nif_decompress_using_ddict in c_src/ezstd_nif.cc reads the frame's declared content size with ZSTD_getFrameContentSize and passes it directly to enif_make_new_binary, without the 1 GiB MAX_BUFFER_SIZE check that ezstd:decompress/1 applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by ezstd:decompress/1 but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process. This issue affects ezstd: from 1.0.5 before 1.2.5.
    SSVC
    Exploitation: none Automatable: no Technical Impact: partial
    CISA Coordinator · CISA-ADP (v2.0.3)
    Decision recorded 2026-11-05 20:45 UTC
    CWE
    • CWE-409 - Improper Handling of Highly Compressed Data (Data Amplification)
    Assigner
    EEF CNA under the mitre root
    CNA scorecard A 97/100 over 351 records in the last 180 days details
    Impacted products
    Vendor Product Version
    silviucpp ezstd Affected: 1.0.5 , < 1.2.5 (semver)
        cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*
    Create a notification for this product.
    silviucpp ezstd Affected: 6730128b1d35eca02a2028671421471ff651f423 , < e34f4a4f6dc18d990d1cece2d5fceef8e934a195 (git)
        cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*
    Create a notification for this product.
    Show details on NVD website

    {
      "containers": {
        "adp": [
          {
            "metrics": [
              {
                "cvssV3_1": {
                  "attackComplexity": "LOW",
                  "attackVector": "LOCAL",
                  "availabilityImpact": "HIGH",
                  "baseScore": 6.2,
                  "baseSeverity": "MEDIUM",
                  "confidentialityImpact": "NONE",
                  "integrityImpact": "NONE",
                  "privilegesRequired": "NONE",
                  "scope": "UNCHANGED",
                  "userInteraction": "NONE",
                  "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
                  "version": "3.1"
                }
              },
              {
                "other": {
                  "content": {
                    "id": "CVE-2026-119434",
                    "options": [
                      {
                        "Exploitation": "none"
                      },
                      {
                        "Automatable": "no"
                      },
                      {
                        "Technical Impact": "partial"
                      }
                    ],
                    "role": "CISA Coordinator",
                    "timestamp": "2026-11-05T20:45:27.204341Z",
                    "version": "2.0.3"
                  },
                  "type": "ssvc"
                }
              }
            ],
            "providerMetadata": {
              "dateUpdated": "2026-11-05T20:45:33.490Z",
              "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
              "shortName": "CISA-ADP"
            },
            "title": "CISA ADP Vulnrichment"
          }
        ],
        "cna": {
          "affected": [
            {
              "collectionURL": "https://repo.hex.pm",
              "cpes": [
                "cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*"
              ],
              "defaultStatus": "unaffected",
              "modules": [
                "ezstd_nif",
                "ezstd"
              ],
              "packageName": "ezstd",
              "packageURL": "pkg:hex/ezstd",
              "product": "ezstd",
              "programFiles": [
                "c_src/ezstd_nif.cc",
                "src/ezstd_nif.erl",
                "src/ezstd.erl"
              ],
              "programRoutines": [
                {
                  "name": "zstd_nif_decompress_using_ddict"
                },
                {
                  "name": "ezstd_nif:decompress_using_ddict/2"
                },
                {
                  "name": "ezstd:decompress_using_ddict/2"
                }
              ],
              "repo": "https://github.com/silviucpp/ezstd",
              "vendor": "silviucpp",
              "versions": [
                {
                  "lessThan": "1.2.5",
                  "status": "affected",
                  "version": "1.0.5",
                  "versionType": "semver"
                }
              ]
            },
            {
              "collectionURL": "https://github.com",
              "cpes": [
                "cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*"
              ],
              "defaultStatus": "unaffected",
              "modules": [
                "ezstd_nif",
                "ezstd"
              ],
              "packageName": "silviucpp/ezstd",
              "packageURL": "pkg:github/silviucpp/ezstd",
              "product": "ezstd",
              "programFiles": [
                "c_src/ezstd_nif.cc",
                "src/ezstd_nif.erl",
                "src/ezstd.erl"
              ],
              "programRoutines": [
                {
                  "name": "zstd_nif_decompress_using_ddict"
                },
                {
                  "name": "ezstd_nif:decompress_using_ddict/2"
                },
                {
                  "name": "ezstd:decompress_using_ddict/2"
                }
              ],
              "repo": "https://github.com/silviucpp/ezstd",
              "vendor": "silviucpp",
              "versions": [
                {
                  "lessThan": "e34f4a4f6dc18d990d1cece2d5fceef8e934a195",
                  "status": "affected",
                  "version": "6730128b1d35eca02a2028671421471ff651f423",
                  "versionType": "git"
                }
              ]
            }
          ],
          "cpeApplicability": [
            {
              "nodes": [
                {
                  "cpeMatch": [
                    {
                      "criteria": "cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*",
                      "versionEndExcluding": "1.2.5",
                      "versionStartIncluding": "1.0.5",
                      "vulnerable": true
                    }
                  ],
                  "negate": false,
                  "operator": "OR"
                }
              ],
              "operator": "AND"
            }
          ],
          "credits": [
            {
              "lang": "en",
              "type": "finder",
              "value": "Oz Kaiser"
            },
            {
              "lang": "en",
              "type": "reporter",
              "value": "Oz Kaiser"
            },
            {
              "lang": "en",
              "type": "remediation developer",
              "value": "Silviu Caragea"
            },
            {
              "lang": "en",
              "type": "coordinator",
              "value": "Jonatan M\u00e4nnchen / EEF"
            }
          ],
          "dateAssigned": "2026-11-04T17:02:50.000Z",
          "descriptions": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003cp\u003eImproper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to \u003ccode\u003eezstd:decompress_using_ddict/2\u003c/code\u003e to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003ezstd_nif_decompress_using_ddict\u003c/code\u003e in \u003ccode\u003ec_src/ezstd_nif.cc\u003c/code\u003e reads the frame\u0027s declared content size with \u003ccode\u003eZSTD_getFrameContentSize\u003c/code\u003e and passes it directly to \u003ccode\u003eenif_make_new_binary\u003c/code\u003e, without the 1 GiB \u003ccode\u003eMAX_BUFFER_SIZE\u003c/code\u003e check that \u003ccode\u003eezstd:decompress/1\u003c/code\u003e applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by \u003ccode\u003eezstd:decompress/1\u003c/code\u003e but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process.\u003c/p\u003e\n\u003cp\u003eThis issue affects ezstd: from 1.0.5 before 1.2.5.\u003c/p\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to `ezstd:decompress_using_ddict/2` to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size.\n\n`zstd_nif_decompress_using_ddict` in `c_src/ezstd_nif.cc` reads the frame\u0027s declared content size with `ZSTD_getFrameContentSize` and passes it directly to `enif_make_new_binary`, without the 1 GiB `MAX_BUFFER_SIZE` check that `ezstd:decompress/1` applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by `ezstd:decompress/1` but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process.\n\nThis issue affects ezstd: from 1.0.5 before 1.2.5."
                }
              ],
              "value": "Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to ezstd:decompress_using_ddict/2 to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size.\n\nzstd_nif_decompress_using_ddict in c_src/ezstd_nif.cc reads the frame\u0027s declared content size with ZSTD_getFrameContentSize and passes it directly to enif_make_new_binary, without the 1 GiB MAX_BUFFER_SIZE check that ezstd:decompress/1 applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by ezstd:decompress/1 but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process.\n\nThis issue affects ezstd: from 1.0.5 before 1.2.5."
            }
          ],
          "impacts": [
            {
              "capecId": "CAPEC-130",
              "descriptions": [
                {
                  "lang": "en",
                  "supportingMedia": [
                    {
                      "base64": false,
                      "type": "text/html",
                      "value": "\u003cp\u003eAn attacker who can submit a zstd frame to a service that decompresses it with a fixed dictionary can crash the entire Erlang VM with a single request of about 65 KiB. Every application and process hosted in that VM is taken down, not only the one that called the decompressor.\u003c/p\u003e"
                    },
                    {
                      "base64": false,
                      "type": "text/markdown",
                      "value": "An attacker who can submit a zstd frame to a service that decompresses it with a fixed dictionary can crash the entire Erlang VM with a single request of about 65 KiB. Every application and process hosted in that VM is taken down, not only the one that called the decompressor."
                    }
                  ],
                  "value": "An attacker who can submit a zstd frame to a service that decompresses it with a fixed dictionary can crash the entire Erlang VM with a single request of about 65 KiB. Every application and process hosted in that VM is taken down, not only the one that called the decompressor."
                }
              ]
            }
          ],
          "metrics": [
            {
              "cvssV4_0": {
                "Automatable": "NOT_DEFINED",
                "Recovery": "NOT_DEFINED",
                "Safety": "NOT_DEFINED",
                "attackComplexity": "LOW",
                "attackRequirements": "NONE",
                "attackVector": "LOCAL",
                "baseScore": 6.9,
                "baseSeverity": "MEDIUM",
                "privilegesRequired": "NONE",
                "providerUrgency": "NOT_DEFINED",
                "subAvailabilityImpact": "NONE",
                "subConfidentialityImpact": "NONE",
                "subIntegrityImpact": "NONE",
                "userInteraction": "NONE",
                "valueDensity": "NOT_DEFINED",
                "vectorString": "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
                "version": "4.0",
                "vulnAvailabilityImpact": "HIGH",
                "vulnConfidentialityImpact": "NONE",
                "vulnIntegrityImpact": "NONE",
                "vulnerabilityResponseEffort": "NOT_DEFINED"
              },
              "format": "CVSS",
              "scenarios": [
                {
                  "lang": "en",
                  "value": "GENERAL"
                }
              ]
            }
          ],
          "problemTypes": [
            {
              "descriptions": [
                {
                  "cweId": "CWE-409",
                  "description": "CWE-409 Improper Handling of Highly Compressed Data (Data Amplification)",
                  "lang": "en",
                  "type": "CWE"
                }
              ]
            }
          ],
          "providerMetadata": {
            "dateUpdated": "2026-11-05T20:15:56.311Z",
            "orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "shortName": "EEF"
          },
          "references": [
            {
              "name": "ezstd v1.2.5 release notes",
              "tags": [
                "release-notes",
                "related"
              ],
              "url": "https://github.com/silviucpp/ezstd/releases/tag/v1.2.5"
            },
            {
              "name": "EEF CNA record for CVE-2026-119434",
              "tags": [
                "related",
                "third-party-advisory"
              ],
              "url": "https://cna.erlef.org/cves/CVE-2026-119434.html"
            },
            {
              "name": "OSV record EEF-CVE-2026-119434",
              "tags": [
                "related"
              ],
              "url": "https://osv.dev/vulnerability/EEF-CVE-2026-119434"
            },
            {
              "name": "Introducing commit 6730128 in silviucpp/ezstd",
              "tags": [
                "related"
              ],
              "url": "https://github.com/silviucpp/ezstd/commit/6730128b1d35eca02a2028671421471ff651f423"
            },
            {
              "name": "Fix commit e34f4a4 in silviucpp/ezstd",
              "tags": [
                "patch"
              ],
              "url": "https://github.com/silviucpp/ezstd/commit/e34f4a4f6dc18d990d1cece2d5fceef8e934a195"
            }
          ],
          "source": {
            "discovery": "EXTERNAL"
          },
          "title": "Decompression bomb in ezstd:decompress_using_ddict/2 allows BEAM memory exhaustion via unbounded output buffer",
          "workarounds": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003cp\u003eReplace calls to \u003ccode\u003eezstd:decompress_using_ddict/2\u003c/code\u003e with the streaming API: create a context with \u003ccode\u003eezstd:create_decompression_context/1\u003c/code\u003e using a small output buffer, attach the dictionary with \u003ccode\u003eezstd:select_ddict/2\u003c/code\u003e, and decompress with \u003ccode\u003eezstd:decompress_streaming/2\u003c/code\u003e. The streaming path decompresses into the caller-sized buffer and gives up with \u003ccode\u003e{error, decompressor_stuck}\u003c/code\u003e after 1000 chunks, so a 64 KiB buffer caps a single call at 64 MiB of output. Treat that error as a rejected input. Legitimate frames whose output exceeds 1000 times the buffer size fail the same way, so size the buffer for the largest expected payload.\u003c/p\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "Replace calls to `ezstd:decompress_using_ddict/2` with the streaming API: create a context with `ezstd:create_decompression_context/1` using a small output buffer, attach the dictionary with `ezstd:select_ddict/2`, and decompress with `ezstd:decompress_streaming/2`. The streaming path decompresses into the caller-sized buffer and gives up with `{error, decompressor_stuck}` after 1000 chunks, so a 64 KiB buffer caps a single call at 64 MiB of output. Treat that error as a rejected input. Legitimate frames whose output exceeds 1000 times the buffer size fail the same way, so size the buffer for the largest expected payload."
                }
              ],
              "value": "Replace calls to ezstd:decompress_using_ddict/2 with the streaming API: create a context with ezstd:create_decompression_context/1 using a small output buffer, attach the dictionary with ezstd:select_ddict/2, and decompress with ezstd:decompress_streaming/2. The streaming path decompresses into the caller-sized buffer and gives up with {error, decompressor_stuck} after 1000 chunks, so a 64 KiB buffer caps a single call at 64 MiB of output. Treat that error as a rejected input. Legitimate frames whose output exceeds 1000 times the buffer size fail the same way, so size the buffer for the largest expected payload."
            }
          ],
          "x_proofOfConcept": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003col\u003e\n\u003cli\u003eBuild ezstd 1.2.4 and start a VM under an external memory limit, for example a container limited to 256 MiB.\u003c/li\u003e\n\u003cli\u003eCreate any decompression dictionary with \u003ccode\u003eezstd:create_ddict/1\u003c/code\u003e; its content does not matter because the frame carries no dictionary ID.\u003c/li\u003e\n\u003cli\u003eConstruct a zstd frame: the magic number, a frame header descriptor selecting an 8-byte content size, a window descriptor, a little-endian content size of 2 GiB, then 16,383 RLE blocks of 128 KiB each (block header \u003ccode\u003e0x02 0x00 0x10\u003c/code\u003e followed by one payload byte) and a final RLE block with the last-block bit set. The frame is 65,550 bytes.\u003c/li\u003e\n\u003cli\u003eCall \u003ccode\u003eezstd:decompress/1\u003c/code\u003e on the frame: it returns \u003ccode\u003e{error, \u0026lt;\u0026lt;\"frame too large or invalid\"\u0026gt;\u0026gt;}\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eCall \u003ccode\u003eezstd:decompress_using_ddict/2\u003c/code\u003e on the same frame with the dictionary: the VM is killed by the operating system (exit status 137).\u003c/li\u003e\n\u003cli\u003eRepeat on 1.2.5: the call returns \u003ccode\u003e{error, \u0026lt;\u0026lt;\"frame too large or invalid\"\u0026gt;\u0026gt;}\u003c/code\u003e and the VM continues.\u003c/li\u003e\n\u003c/ol\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "1. Build ezstd 1.2.4 and start a VM under an external memory limit, for example a container limited to 256 MiB.\n2. Create any decompression dictionary with `ezstd:create_ddict/1`; its content does not matter because the frame carries no dictionary ID.\n3. Construct a zstd frame: the magic number, a frame header descriptor selecting an 8-byte content size, a window descriptor, a little-endian content size of 2 GiB, then 16,383 RLE blocks of 128 KiB each (block header `0x02 0x00 0x10` followed by one payload byte) and a final RLE block with the last-block bit set. The frame is 65,550 bytes.\n4. Call `ezstd:decompress/1` on the frame: it returns `{error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e}`.\n5. Call `ezstd:decompress_using_ddict/2` on the same frame with the dictionary: the VM is killed by the operating system (exit status 137).\n6. Repeat on 1.2.5: the call returns `{error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e}` and the VM continues."
                }
              ],
              "value": "* Build ezstd 1.2.4 and start a VM under an external memory limit, for example a container limited to 256 MiB.\n* Create any decompression dictionary with ezstd:create_ddict/1; its content does not matter because the frame carries no dictionary ID.\n* Construct a zstd frame: the magic number, a frame header descriptor selecting an 8-byte content size, a window descriptor, a little-endian content size of 2 GiB, then 16,383 RLE blocks of 128 KiB each (block header 0x02 0x00 0x10 followed by one payload byte) and a final RLE block with the last-block bit set. The frame is 65,550 bytes.\n* Call ezstd:decompress/1 on the frame: it returns {error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e}.\n* Call ezstd:decompress_using_ddict/2 on the same frame with the dictionary: the VM is killed by the operating system (exit status 137).\n* Repeat on 1.2.5: the call returns {error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e} and the VM continues."
            }
          ],
          "x_technicalAnalysis": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003cp\u003e\u003cstrong\u003e1. Declared size is attacker controlled.\u003c/strong\u003e A zstd frame header carries an optional Frame Content Size field. \u003ccode\u003ezstd_nif_decompress_using_ddict\u003c/code\u003e in \u003ccode\u003ec_src/ezstd_nif.cc\u003c/code\u003e reads it with \u003ccode\u003eZSTD_getFrameContentSize\u003c/code\u003e and rejects only the two sentinel values \u003ccode\u003eZSTD_CONTENTSIZE_UNKNOWN\u003c/code\u003e and \u003ccode\u003eZSTD_CONTENTSIZE_ERROR\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e2. Unbounded allocation.\u003c/strong\u003e The size is passed directly to \u003ccode\u003eenif_make_new_binary\u003c/code\u003e, so a frame declaring 2 GiB makes the NIF request a 2 GiB binary. The sibling \u003ccode\u003ezstd_nif_decompress\u003c/code\u003e rejects any declared size above \u003ccode\u003eMAX_BUFFER_SIZE\u003c/code\u003e (1 GiB) before allocating; the dictionary path omitted that check from the commit that introduced it.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e3. Amplification.\u003c/strong\u003e A frame built from RLE blocks, each encoding 128 KiB of a repeated byte in four bytes, declares and genuinely decompresses to 2 GiB from 65,550 bytes of input, a ratio of about 32,760:1. \u003ccode\u003eZSTD_decompress_usingDDict\u003c/code\u003e then fills the buffer. Because this happens inside a NIF, exceeding the memory available to the VM results in the operating system killing the whole BEAM process rather than an Erlang-level exception.\u003c/p\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "**1. Declared size is attacker controlled.** A zstd frame header carries an optional Frame Content Size field. `zstd_nif_decompress_using_ddict` in `c_src/ezstd_nif.cc` reads it with `ZSTD_getFrameContentSize` and rejects only the two sentinel values `ZSTD_CONTENTSIZE_UNKNOWN` and `ZSTD_CONTENTSIZE_ERROR`.\n\n**2. Unbounded allocation.** The size is passed directly to `enif_make_new_binary`, so a frame declaring 2 GiB makes the NIF request a 2 GiB binary. The sibling `zstd_nif_decompress` rejects any declared size above `MAX_BUFFER_SIZE` (1 GiB) before allocating; the dictionary path omitted that check from the commit that introduced it.\n\n**3. Amplification.** A frame built from RLE blocks, each encoding 128 KiB of a repeated byte in four bytes, declares and genuinely decompresses to 2 GiB from 65,550 bytes of input, a ratio of about 32,760:1. `ZSTD_decompress_usingDDict` then fills the buffer. Because this happens inside a NIF, exceeding the memory available to the VM results in the operating system killing the whole BEAM process rather than an Erlang-level exception."
                }
              ],
              "value": "1. Declared size is attacker controlled. A zstd frame header carries an optional Frame Content Size field. zstd_nif_decompress_using_ddict in c_src/ezstd_nif.cc reads it with ZSTD_getFrameContentSize and rejects only the two sentinel values ZSTD_CONTENTSIZE_UNKNOWN and ZSTD_CONTENTSIZE_ERROR.\n\n2. Unbounded allocation. The size is passed directly to enif_make_new_binary, so a frame declaring 2 GiB makes the NIF request a 2 GiB binary. The sibling zstd_nif_decompress rejects any declared size above MAX_BUFFER_SIZE (1 GiB) before allocating; the dictionary path omitted that check from the commit that introduced it.\n\n3. Amplification. A frame built from RLE blocks, each encoding 128 KiB of a repeated byte in four bytes, declares and genuinely decompresses to 2 GiB from 65,550 bytes of input, a ratio of about 32,760:1. ZSTD_decompress_usingDDict then fills the buffer. Because this happens inside a NIF, exceeding the memory available to the VM results in the operating system killing the whole BEAM process rather than an Erlang-level exception."
            }
          ]
        }
      },
      "cveMetadata": {
        "assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "assignerShortName": "EEF",
        "cveId": "CVE-2026-119434",
        "datePublished": "2026-11-05T20:15:56.311Z",
        "dateReserved": "2026-10-30T10:30:01.015Z",
        "dateUpdated": "2026-11-05T20:45:33.490Z",
        "state": "PUBLISHED"
      },
      "dataType": "CVE_RECORD",
      "dataVersion": "5.2"
    }

    CVE-2026-119434 (GCVE-0-2026-119434)

    Vulnerability from cvelistv5 – Published: 2026-11-05 20:15 – Updated: 2026-11-05 20:45
    VLAI
    Title
    Decompression bomb in ezstd:decompress_using_ddict/2 allows BEAM memory exhaustion via unbounded output buffer
    Summary
    Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to ezstd:decompress_using_ddict/2 to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size. zstd_nif_decompress_using_ddict in c_src/ezstd_nif.cc reads the frame's declared content size with ZSTD_getFrameContentSize and passes it directly to enif_make_new_binary, without the 1 GiB MAX_BUFFER_SIZE check that ezstd:decompress/1 applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by ezstd:decompress/1 but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process. This issue affects ezstd: from 1.0.5 before 1.2.5.
    SSVC
    Exploitation: none Automatable: no Technical Impact: partial
    CISA Coordinator · CISA-ADP (v2.0.3)
    Decision recorded 2026-11-05 20:45 UTC
    CWE
    • CWE-409 - Improper Handling of Highly Compressed Data (Data Amplification)
    Assigner
    EEF CNA under the mitre root
    CNA scorecard A 97/100 over 351 records in the last 180 days details
    Impacted products
    Vendor Product Version
    silviucpp ezstd Affected: 1.0.5 , < 1.2.5 (semver)
        cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*
    Create a notification for this product.
    silviucpp ezstd Affected: 6730128b1d35eca02a2028671421471ff651f423 , < e34f4a4f6dc18d990d1cece2d5fceef8e934a195 (git)
        cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*
    Create a notification for this product.
    Show details on NVD website

    {
      "containers": {
        "adp": [
          {
            "metrics": [
              {
                "cvssV3_1": {
                  "attackComplexity": "LOW",
                  "attackVector": "LOCAL",
                  "availabilityImpact": "HIGH",
                  "baseScore": 6.2,
                  "baseSeverity": "MEDIUM",
                  "confidentialityImpact": "NONE",
                  "integrityImpact": "NONE",
                  "privilegesRequired": "NONE",
                  "scope": "UNCHANGED",
                  "userInteraction": "NONE",
                  "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
                  "version": "3.1"
                }
              },
              {
                "other": {
                  "content": {
                    "id": "CVE-2026-119434",
                    "options": [
                      {
                        "Exploitation": "none"
                      },
                      {
                        "Automatable": "no"
                      },
                      {
                        "Technical Impact": "partial"
                      }
                    ],
                    "role": "CISA Coordinator",
                    "timestamp": "2026-11-05T20:45:27.204341Z",
                    "version": "2.0.3"
                  },
                  "type": "ssvc"
                }
              }
            ],
            "providerMetadata": {
              "dateUpdated": "2026-11-05T20:45:33.490Z",
              "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
              "shortName": "CISA-ADP"
            },
            "title": "CISA ADP Vulnrichment"
          }
        ],
        "cna": {
          "affected": [
            {
              "collectionURL": "https://repo.hex.pm",
              "cpes": [
                "cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*"
              ],
              "defaultStatus": "unaffected",
              "modules": [
                "ezstd_nif",
                "ezstd"
              ],
              "packageName": "ezstd",
              "packageURL": "pkg:hex/ezstd",
              "product": "ezstd",
              "programFiles": [
                "c_src/ezstd_nif.cc",
                "src/ezstd_nif.erl",
                "src/ezstd.erl"
              ],
              "programRoutines": [
                {
                  "name": "zstd_nif_decompress_using_ddict"
                },
                {
                  "name": "ezstd_nif:decompress_using_ddict/2"
                },
                {
                  "name": "ezstd:decompress_using_ddict/2"
                }
              ],
              "repo": "https://github.com/silviucpp/ezstd",
              "vendor": "silviucpp",
              "versions": [
                {
                  "lessThan": "1.2.5",
                  "status": "affected",
                  "version": "1.0.5",
                  "versionType": "semver"
                }
              ]
            },
            {
              "collectionURL": "https://github.com",
              "cpes": [
                "cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*"
              ],
              "defaultStatus": "unaffected",
              "modules": [
                "ezstd_nif",
                "ezstd"
              ],
              "packageName": "silviucpp/ezstd",
              "packageURL": "pkg:github/silviucpp/ezstd",
              "product": "ezstd",
              "programFiles": [
                "c_src/ezstd_nif.cc",
                "src/ezstd_nif.erl",
                "src/ezstd.erl"
              ],
              "programRoutines": [
                {
                  "name": "zstd_nif_decompress_using_ddict"
                },
                {
                  "name": "ezstd_nif:decompress_using_ddict/2"
                },
                {
                  "name": "ezstd:decompress_using_ddict/2"
                }
              ],
              "repo": "https://github.com/silviucpp/ezstd",
              "vendor": "silviucpp",
              "versions": [
                {
                  "lessThan": "e34f4a4f6dc18d990d1cece2d5fceef8e934a195",
                  "status": "affected",
                  "version": "6730128b1d35eca02a2028671421471ff651f423",
                  "versionType": "git"
                }
              ]
            }
          ],
          "cpeApplicability": [
            {
              "nodes": [
                {
                  "cpeMatch": [
                    {
                      "criteria": "cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*",
                      "versionEndExcluding": "1.2.5",
                      "versionStartIncluding": "1.0.5",
                      "vulnerable": true
                    }
                  ],
                  "negate": false,
                  "operator": "OR"
                }
              ],
              "operator": "AND"
            }
          ],
          "credits": [
            {
              "lang": "en",
              "type": "finder",
              "value": "Oz Kaiser"
            },
            {
              "lang": "en",
              "type": "reporter",
              "value": "Oz Kaiser"
            },
            {
              "lang": "en",
              "type": "remediation developer",
              "value": "Silviu Caragea"
            },
            {
              "lang": "en",
              "type": "coordinator",
              "value": "Jonatan M\u00e4nnchen / EEF"
            }
          ],
          "dateAssigned": "2026-11-04T17:02:50.000Z",
          "descriptions": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003cp\u003eImproper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to \u003ccode\u003eezstd:decompress_using_ddict/2\u003c/code\u003e to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003ezstd_nif_decompress_using_ddict\u003c/code\u003e in \u003ccode\u003ec_src/ezstd_nif.cc\u003c/code\u003e reads the frame\u0027s declared content size with \u003ccode\u003eZSTD_getFrameContentSize\u003c/code\u003e and passes it directly to \u003ccode\u003eenif_make_new_binary\u003c/code\u003e, without the 1 GiB \u003ccode\u003eMAX_BUFFER_SIZE\u003c/code\u003e check that \u003ccode\u003eezstd:decompress/1\u003c/code\u003e applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by \u003ccode\u003eezstd:decompress/1\u003c/code\u003e but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process.\u003c/p\u003e\n\u003cp\u003eThis issue affects ezstd: from 1.0.5 before 1.2.5.\u003c/p\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to `ezstd:decompress_using_ddict/2` to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size.\n\n`zstd_nif_decompress_using_ddict` in `c_src/ezstd_nif.cc` reads the frame\u0027s declared content size with `ZSTD_getFrameContentSize` and passes it directly to `enif_make_new_binary`, without the 1 GiB `MAX_BUFFER_SIZE` check that `ezstd:decompress/1` applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by `ezstd:decompress/1` but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process.\n\nThis issue affects ezstd: from 1.0.5 before 1.2.5."
                }
              ],
              "value": "Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to ezstd:decompress_using_ddict/2 to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size.\n\nzstd_nif_decompress_using_ddict in c_src/ezstd_nif.cc reads the frame\u0027s declared content size with ZSTD_getFrameContentSize and passes it directly to enif_make_new_binary, without the 1 GiB MAX_BUFFER_SIZE check that ezstd:decompress/1 applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by ezstd:decompress/1 but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process.\n\nThis issue affects ezstd: from 1.0.5 before 1.2.5."
            }
          ],
          "impacts": [
            {
              "capecId": "CAPEC-130",
              "descriptions": [
                {
                  "lang": "en",
                  "supportingMedia": [
                    {
                      "base64": false,
                      "type": "text/html",
                      "value": "\u003cp\u003eAn attacker who can submit a zstd frame to a service that decompresses it with a fixed dictionary can crash the entire Erlang VM with a single request of about 65 KiB. Every application and process hosted in that VM is taken down, not only the one that called the decompressor.\u003c/p\u003e"
                    },
                    {
                      "base64": false,
                      "type": "text/markdown",
                      "value": "An attacker who can submit a zstd frame to a service that decompresses it with a fixed dictionary can crash the entire Erlang VM with a single request of about 65 KiB. Every application and process hosted in that VM is taken down, not only the one that called the decompressor."
                    }
                  ],
                  "value": "An attacker who can submit a zstd frame to a service that decompresses it with a fixed dictionary can crash the entire Erlang VM with a single request of about 65 KiB. Every application and process hosted in that VM is taken down, not only the one that called the decompressor."
                }
              ]
            }
          ],
          "metrics": [
            {
              "cvssV4_0": {
                "Automatable": "NOT_DEFINED",
                "Recovery": "NOT_DEFINED",
                "Safety": "NOT_DEFINED",
                "attackComplexity": "LOW",
                "attackRequirements": "NONE",
                "attackVector": "LOCAL",
                "baseScore": 6.9,
                "baseSeverity": "MEDIUM",
                "privilegesRequired": "NONE",
                "providerUrgency": "NOT_DEFINED",
                "subAvailabilityImpact": "NONE",
                "subConfidentialityImpact": "NONE",
                "subIntegrityImpact": "NONE",
                "userInteraction": "NONE",
                "valueDensity": "NOT_DEFINED",
                "vectorString": "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
                "version": "4.0",
                "vulnAvailabilityImpact": "HIGH",
                "vulnConfidentialityImpact": "NONE",
                "vulnIntegrityImpact": "NONE",
                "vulnerabilityResponseEffort": "NOT_DEFINED"
              },
              "format": "CVSS",
              "scenarios": [
                {
                  "lang": "en",
                  "value": "GENERAL"
                }
              ]
            }
          ],
          "problemTypes": [
            {
              "descriptions": [
                {
                  "cweId": "CWE-409",
                  "description": "CWE-409 Improper Handling of Highly Compressed Data (Data Amplification)",
                  "lang": "en",
                  "type": "CWE"
                }
              ]
            }
          ],
          "providerMetadata": {
            "dateUpdated": "2026-11-05T20:15:56.311Z",
            "orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "shortName": "EEF"
          },
          "references": [
            {
              "name": "ezstd v1.2.5 release notes",
              "tags": [
                "release-notes",
                "related"
              ],
              "url": "https://github.com/silviucpp/ezstd/releases/tag/v1.2.5"
            },
            {
              "name": "EEF CNA record for CVE-2026-119434",
              "tags": [
                "related",
                "third-party-advisory"
              ],
              "url": "https://cna.erlef.org/cves/CVE-2026-119434.html"
            },
            {
              "name": "OSV record EEF-CVE-2026-119434",
              "tags": [
                "related"
              ],
              "url": "https://osv.dev/vulnerability/EEF-CVE-2026-119434"
            },
            {
              "name": "Introducing commit 6730128 in silviucpp/ezstd",
              "tags": [
                "related"
              ],
              "url": "https://github.com/silviucpp/ezstd/commit/6730128b1d35eca02a2028671421471ff651f423"
            },
            {
              "name": "Fix commit e34f4a4 in silviucpp/ezstd",
              "tags": [
                "patch"
              ],
              "url": "https://github.com/silviucpp/ezstd/commit/e34f4a4f6dc18d990d1cece2d5fceef8e934a195"
            }
          ],
          "source": {
            "discovery": "EXTERNAL"
          },
          "title": "Decompression bomb in ezstd:decompress_using_ddict/2 allows BEAM memory exhaustion via unbounded output buffer",
          "workarounds": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003cp\u003eReplace calls to \u003ccode\u003eezstd:decompress_using_ddict/2\u003c/code\u003e with the streaming API: create a context with \u003ccode\u003eezstd:create_decompression_context/1\u003c/code\u003e using a small output buffer, attach the dictionary with \u003ccode\u003eezstd:select_ddict/2\u003c/code\u003e, and decompress with \u003ccode\u003eezstd:decompress_streaming/2\u003c/code\u003e. The streaming path decompresses into the caller-sized buffer and gives up with \u003ccode\u003e{error, decompressor_stuck}\u003c/code\u003e after 1000 chunks, so a 64 KiB buffer caps a single call at 64 MiB of output. Treat that error as a rejected input. Legitimate frames whose output exceeds 1000 times the buffer size fail the same way, so size the buffer for the largest expected payload.\u003c/p\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "Replace calls to `ezstd:decompress_using_ddict/2` with the streaming API: create a context with `ezstd:create_decompression_context/1` using a small output buffer, attach the dictionary with `ezstd:select_ddict/2`, and decompress with `ezstd:decompress_streaming/2`. The streaming path decompresses into the caller-sized buffer and gives up with `{error, decompressor_stuck}` after 1000 chunks, so a 64 KiB buffer caps a single call at 64 MiB of output. Treat that error as a rejected input. Legitimate frames whose output exceeds 1000 times the buffer size fail the same way, so size the buffer for the largest expected payload."
                }
              ],
              "value": "Replace calls to ezstd:decompress_using_ddict/2 with the streaming API: create a context with ezstd:create_decompression_context/1 using a small output buffer, attach the dictionary with ezstd:select_ddict/2, and decompress with ezstd:decompress_streaming/2. The streaming path decompresses into the caller-sized buffer and gives up with {error, decompressor_stuck} after 1000 chunks, so a 64 KiB buffer caps a single call at 64 MiB of output. Treat that error as a rejected input. Legitimate frames whose output exceeds 1000 times the buffer size fail the same way, so size the buffer for the largest expected payload."
            }
          ],
          "x_proofOfConcept": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003col\u003e\n\u003cli\u003eBuild ezstd 1.2.4 and start a VM under an external memory limit, for example a container limited to 256 MiB.\u003c/li\u003e\n\u003cli\u003eCreate any decompression dictionary with \u003ccode\u003eezstd:create_ddict/1\u003c/code\u003e; its content does not matter because the frame carries no dictionary ID.\u003c/li\u003e\n\u003cli\u003eConstruct a zstd frame: the magic number, a frame header descriptor selecting an 8-byte content size, a window descriptor, a little-endian content size of 2 GiB, then 16,383 RLE blocks of 128 KiB each (block header \u003ccode\u003e0x02 0x00 0x10\u003c/code\u003e followed by one payload byte) and a final RLE block with the last-block bit set. The frame is 65,550 bytes.\u003c/li\u003e\n\u003cli\u003eCall \u003ccode\u003eezstd:decompress/1\u003c/code\u003e on the frame: it returns \u003ccode\u003e{error, \u0026lt;\u0026lt;\"frame too large or invalid\"\u0026gt;\u0026gt;}\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eCall \u003ccode\u003eezstd:decompress_using_ddict/2\u003c/code\u003e on the same frame with the dictionary: the VM is killed by the operating system (exit status 137).\u003c/li\u003e\n\u003cli\u003eRepeat on 1.2.5: the call returns \u003ccode\u003e{error, \u0026lt;\u0026lt;\"frame too large or invalid\"\u0026gt;\u0026gt;}\u003c/code\u003e and the VM continues.\u003c/li\u003e\n\u003c/ol\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "1. Build ezstd 1.2.4 and start a VM under an external memory limit, for example a container limited to 256 MiB.\n2. Create any decompression dictionary with `ezstd:create_ddict/1`; its content does not matter because the frame carries no dictionary ID.\n3. Construct a zstd frame: the magic number, a frame header descriptor selecting an 8-byte content size, a window descriptor, a little-endian content size of 2 GiB, then 16,383 RLE blocks of 128 KiB each (block header `0x02 0x00 0x10` followed by one payload byte) and a final RLE block with the last-block bit set. The frame is 65,550 bytes.\n4. Call `ezstd:decompress/1` on the frame: it returns `{error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e}`.\n5. Call `ezstd:decompress_using_ddict/2` on the same frame with the dictionary: the VM is killed by the operating system (exit status 137).\n6. Repeat on 1.2.5: the call returns `{error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e}` and the VM continues."
                }
              ],
              "value": "* Build ezstd 1.2.4 and start a VM under an external memory limit, for example a container limited to 256 MiB.\n* Create any decompression dictionary with ezstd:create_ddict/1; its content does not matter because the frame carries no dictionary ID.\n* Construct a zstd frame: the magic number, a frame header descriptor selecting an 8-byte content size, a window descriptor, a little-endian content size of 2 GiB, then 16,383 RLE blocks of 128 KiB each (block header 0x02 0x00 0x10 followed by one payload byte) and a final RLE block with the last-block bit set. The frame is 65,550 bytes.\n* Call ezstd:decompress/1 on the frame: it returns {error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e}.\n* Call ezstd:decompress_using_ddict/2 on the same frame with the dictionary: the VM is killed by the operating system (exit status 137).\n* Repeat on 1.2.5: the call returns {error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e} and the VM continues."
            }
          ],
          "x_technicalAnalysis": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003cp\u003e\u003cstrong\u003e1. Declared size is attacker controlled.\u003c/strong\u003e A zstd frame header carries an optional Frame Content Size field. \u003ccode\u003ezstd_nif_decompress_using_ddict\u003c/code\u003e in \u003ccode\u003ec_src/ezstd_nif.cc\u003c/code\u003e reads it with \u003ccode\u003eZSTD_getFrameContentSize\u003c/code\u003e and rejects only the two sentinel values \u003ccode\u003eZSTD_CONTENTSIZE_UNKNOWN\u003c/code\u003e and \u003ccode\u003eZSTD_CONTENTSIZE_ERROR\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e2. Unbounded allocation.\u003c/strong\u003e The size is passed directly to \u003ccode\u003eenif_make_new_binary\u003c/code\u003e, so a frame declaring 2 GiB makes the NIF request a 2 GiB binary. The sibling \u003ccode\u003ezstd_nif_decompress\u003c/code\u003e rejects any declared size above \u003ccode\u003eMAX_BUFFER_SIZE\u003c/code\u003e (1 GiB) before allocating; the dictionary path omitted that check from the commit that introduced it.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e3. Amplification.\u003c/strong\u003e A frame built from RLE blocks, each encoding 128 KiB of a repeated byte in four bytes, declares and genuinely decompresses to 2 GiB from 65,550 bytes of input, a ratio of about 32,760:1. \u003ccode\u003eZSTD_decompress_usingDDict\u003c/code\u003e then fills the buffer. Because this happens inside a NIF, exceeding the memory available to the VM results in the operating system killing the whole BEAM process rather than an Erlang-level exception.\u003c/p\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "**1. Declared size is attacker controlled.** A zstd frame header carries an optional Frame Content Size field. `zstd_nif_decompress_using_ddict` in `c_src/ezstd_nif.cc` reads it with `ZSTD_getFrameContentSize` and rejects only the two sentinel values `ZSTD_CONTENTSIZE_UNKNOWN` and `ZSTD_CONTENTSIZE_ERROR`.\n\n**2. Unbounded allocation.** The size is passed directly to `enif_make_new_binary`, so a frame declaring 2 GiB makes the NIF request a 2 GiB binary. The sibling `zstd_nif_decompress` rejects any declared size above `MAX_BUFFER_SIZE` (1 GiB) before allocating; the dictionary path omitted that check from the commit that introduced it.\n\n**3. Amplification.** A frame built from RLE blocks, each encoding 128 KiB of a repeated byte in four bytes, declares and genuinely decompresses to 2 GiB from 65,550 bytes of input, a ratio of about 32,760:1. `ZSTD_decompress_usingDDict` then fills the buffer. Because this happens inside a NIF, exceeding the memory available to the VM results in the operating system killing the whole BEAM process rather than an Erlang-level exception."
                }
              ],
              "value": "1. Declared size is attacker controlled. A zstd frame header carries an optional Frame Content Size field. zstd_nif_decompress_using_ddict in c_src/ezstd_nif.cc reads it with ZSTD_getFrameContentSize and rejects only the two sentinel values ZSTD_CONTENTSIZE_UNKNOWN and ZSTD_CONTENTSIZE_ERROR.\n\n2. Unbounded allocation. The size is passed directly to enif_make_new_binary, so a frame declaring 2 GiB makes the NIF request a 2 GiB binary. The sibling zstd_nif_decompress rejects any declared size above MAX_BUFFER_SIZE (1 GiB) before allocating; the dictionary path omitted that check from the commit that introduced it.\n\n3. Amplification. A frame built from RLE blocks, each encoding 128 KiB of a repeated byte in four bytes, declares and genuinely decompresses to 2 GiB from 65,550 bytes of input, a ratio of about 32,760:1. ZSTD_decompress_usingDDict then fills the buffer. Because this happens inside a NIF, exceeding the memory available to the VM results in the operating system killing the whole BEAM process rather than an Erlang-level exception."
            }
          ]
        }
      },
      "cveMetadata": {
        "assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "assignerShortName": "EEF",
        "cveId": "CVE-2026-119434",
        "datePublished": "2026-11-05T20:15:56.311Z",
        "dateReserved": "2026-10-30T10:30:01.015Z",
        "dateUpdated": "2026-11-05T20:45:33.490Z",
        "state": "PUBLISHED"
      },
      "dataType": "CVE_RECORD",
      "dataVersion": "5.2"
    }