Skip to content

Buffer overflow in `png_image_read_composite` via incorrect palette premultiplication

High
ctruta published GHSA-hfc7-ph9c-wcww Nov 22, 2025

Package

libpng

Affected versions

>= 1.6.0, < 1.6.51

Patched versions

1.6.51

Description

An out-of-bounds read vulnerability exists in png_image_read_composite when processing palette images with PNG_FLAG_OPTIMIZE_ALPHA enabled. The palette compositing code in png_init_read_transformations incorrectly applies background compositing during premultiplication, violating the invariant component ≤ alpha × 257 required by the simplified PNG API.

Technical Analysis

In png_init_read_transformations at line ~1336, the palette expansion code performs:

component += (255-alpha)*png_sRGB_table[outrow[c]];

This calculation produces component values up to 16,776,960 (0x1000800), where (component >> 15) == 512. The subsequent PNG_sRGB_FROM_LINEAR macro in png_image_read_composite performs out-of-bounds array access:

png_sRGB_base[component>>15]    // Accesses png_sRGB_base[512]
png_sRGB_delta[component>>15]   // Accesses png_sRGB_delta[512]
// Both arrays have indices 0-511 only (size 512)

Root Cause: The palette logic fails to distinguish between two execution modes:

  • Non-optimized path: Background compositing during palette expansion (correct)
  • Optimized path (PNG_FLAG_OPTIMIZE_ALPHA): Premultiplication only, with background compositing deferred to png_image_read_composite (violated)

Attack Scenario

  1. Attacker crafts PNG with palette mode (color type 3) and transparency chunk (tRNS).
  2. Victim application uses simplified API (png_image_begin_read_from_* + png_image_finish_read) with alpha-capable format (e.g., PNG_FORMAT_RGBA).
  3. Library enables PNG_FLAG_OPTIMIZE_ALPHA internally for formats with alpha channel.
  4. Palette expansion performs premultiplication with background compositing, violating component ≤ alpha × 257 invariant.
  5. Out-of-bounds access via PNG_sRGB_FROM_LINEAR macro in png_image_read_composite.
  6. Result: Information disclosure via global buffer over-read and/or application crash.

Impact

  • Information disclosure via out-of-bounds read of adjacent memory (CWE-125)
  • Denial of service (application crash)

Remediation

Upgrade to libpng 1.6.51 or newer.

No practical workaround is available. While avoiding alpha-capable formats (e.g., PNG_FORMAT_RGBA) would prevent the vulnerability by not triggering PNG_FLAG_OPTIMIZE_ALPHA, this defeats the purpose of applications requiring alpha channel data. Upgrade is the recommended remediation.

Proof of Concept

Fuzzer input: https://github.com/pnggroup/libpng/files/20434505/issue-1.zip

AddressSanitizer output:

ERROR: AddressSanitizer: global-buffer-overflow
READ of size 2 at 0x00456b00
in png_image_read_composite pngread.c:3566:37
0x00456b00 is located 0 bytes after global variable 'png_sRGB_base'

Fix

PR #751 introduces conditional behavior in png_init_read_transformations:

if (PNG_FLAG_OPTIMIZE_ALPHA is set)
   // Pure premultiplication only
   component = (component * alpha + 127) / 255;
else
   // Original background compositing
   component = png_composite(component, png_sRGB_table[...], alpha);

This ensures component ≤ (alpha × 257), guaranteeing (component >> 15) ≤ 1, well within the valid array bound of 511.

References

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
Required
Scope
Unchanged
Confidentiality
Low
Integrity
None
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:H

CVE ID

CVE-2025-64720

Weaknesses

Out-of-bounds Read

The product reads data past the end, or before the beginning, of the intended buffer. Learn more on MITRE.