Android security tags, read closely by Lightrion

CVE-2026-33636 AI-generated analysis

platform/external/libpng, ARM NEON palette expansion (arm/palette_neon_intrinsics.c)

AI-generated: written from the bulletin and the fixing diffs by claude-fable-5-1, then checked against the code by claude-opus-5-5 (4 corrections). Verify against the commit before relying on it.

Restricts the NEON palette-expansion loops in external/libpng arm/palette_neon_intrinsics.c to full chunks only (loop condition i + pixels_per_chunk <= row_width), drops the post-loop count correction, and undoes the *ddp pre-adjustment before handing the remaining pixels to the scalar fallback.

Root cause

png_do_expand_palette_rgba8_neon and png_do_expand_palette_rgb8_neon iterate `for (i = 0; i < row_width; i += pixels_per_chunk)`. Each iteration loads palette entries indexed by source bytes at sp and stores a full vector (vst1q_u32 of a uint32x4_t for rgba8, i.e. 4 pixels; vst3_u8 for rgb8, 8 pixels per the 'Seeking this back by 8 pixels x 3 bytes' comment) at dp. When row_width is not a multiple of the chunk size, the last iteration still runs with less than a full chunk left. Per the commit message, this allows out-of-bounds reads and writes. The post-loop `if (i != row_width) i -= pixels_per_chunk;` only corrected the returned pixel count after the loop had finished. In addition, *ddp is pre-adjusted at entry by (pixels_per_chunk * element size - 1), and that offset was not undone before the pointer was handed back for the scalar path.

How the fix works

Completeness

Behavior changes

Per major

Unknowns

Back to September 2026 · Findings