stb_image.h: 18-byte TGA header forces ~2.1 GB allocation (per-axis STBI_MAX_DIMENSIONS doesn't bound area)
Hi — while fuzzing stb_image I found that a tiny TGA header alone makes stbi_load*() allocate ~2.1 GB and burn seconds of CPU. Posting publicly per SECURITY.md.
Repro: an 18-byte TGA header (no payload needed):
00 00 02 00 00 00 00 00 00 00 00 00 81 5a 81 5a 20 00
img_type = 2(uncompressed truecolor),bpp = 32→ 4 channels- width = height = 0x5A81 = 23169
Result of stbi_load_from_memory() on this 18-byte file:
ok 23169x23169 ch=4
Maximum resident set size: 2098816 kB (~2.05 GB)
Elapsed: 8.34s
23169×23169×4 = 2,147,210,244 — just under INT_MAX, so stbi__malloc_mad3 (the only guard left after the dims check) accepts it. With bpp=8 the same idea hits the mad3 guard and fails only because the product exceeds INT_MAX, not because of any resource policy.
Cause: STBI_MAX_DIMENSIONS (2^24) is checked per-axis in stbi__tga_load (and the generic load path) — area is never bounded:
if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
...
tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0);
stbi__tga_test() only validates header fields, so no payload is needed at all — the amplification is ~119,000,000× per input byte. Any service decoding untrusted images (uploads/attachments) is exposed to memory + CPU DoS from requests ~100,000× cheaper than the work they cause; under a memory cap the failure is a silent NULL, which makes it hard to notice.
Suggested directions (happy to send a PR for whichever fits the project's style):
- an area check (e.g. reject
w*h > 64<<20by default, overridable), possibly in the common load path so BMP/PSD/PPM get it too; - document that
STBI_MAX_DIMENSIONSis per-axis and that allocation ≈ whcomp can approach INT_MAX bytes from a header-only file; - optionally a
STBI_MAX_IMAGE_AREAknob mirroring the dims one.
Full write-up with methodology and measurements available if useful. Thanks!
Source: nothings/stb