All projects with patches now have outreach docs. 276 new docs covering CWE-407, CWE-312, CWE-362 across C, C++, Java, Python, Go, Rust, C#, PHP, Ruby, JavaScript, Dart, Erlang, R, and more. Outreach gap: 276 -> 0.
2.8 KiB
libjpeg-turbo — CWE-407 Disclosure Brief (libjpeg-turbo-0001)
2026-04-13 · Patch available — awaiting upstream merge
Finding
One O(PC) defect in libjpeg-turbo's PPM colormap reader. The add_map_entry() function in rdcolmap.c uses a linear scan to check for duplicate palette colors, producing O(PC) total cost where P = pixels read and C = palette size (up to 256).
The Defect
libjpeg-turbo-0001 (PATCHED — MEDIUM): src/rdcolmap.c:20
LOCAL(void)
add_map_entry(j_decompress_ptr cinfo, int R, int G, int B)
{
int ncolors = cinfo->actual_number_of_colors;
int index;
// O(C) linear scan for each pixel
for (index = 0; index < ncolors; index++) {
if (colormap0[index] == R && colormap1[index] == G &&
colormap2[index] == B)
return; // already in map
}
}
Called once per pixel in read_ppm_map(). For a PPM color map image with P pixels (up to 65500x65500) and C unique colors (up to 256), total comparisons reach O(P*C). For large PPM files that exhaust the palette early, every subsequent pixel pays the full O(256) scan.
Complexity Proof
At P=100,000 pixels, C=256 colors (palette exhausted early):
- Defective: 100,000 × 256 = 25,600,000 comparisons
- Fixed: 100,000 × O(1) hash lookups = 100,000 operations
- ~256× op reduction.
Impact
libjpeg-turbo is the most widely deployed JPEG codec, used in web browsers (Firefox, Chrome), image editors, and virtually every system that handles JPEG images. The PPM colormap reader processes quantized color palette images. Large PPM files with many pixels trigger the quadratic path.
The Fix
Add a 512-slot open-addressing hash set for O(1) color membership testing:
// Hash table for O(1) color membership
#define CMAP_HASH_SIZE 512
static CmapSlot cmap_seen[CMAP_HASH_SIZE];
LOCAL(int) cmap_hash_seen(int R, int G, int B) {
unsigned int key = (1u << 24) | (R << 16) | (G << 8) | B;
// Fibonacci hashing + linear probe
int slot = ((key & 0xFFFFFFu) * 2654435761u) >> (32 - 9);
// ... O(1) average lookup
}
Patch
Fix available: defects/libjpeg-turbo-0001/patch/libjpeg-turbo-0001-rdcolmap-ppm-color-dedup.patch
Single-file patch in src/rdcolmap.c. Adds static hash set, resets in _read_color_map(). ~256× speedup at 256 palette colors.
What We Ask
A patch is ready for review.
- Confirm receipt and assign a GitHub issue reference (libjpeg-turbo/libjpeg-turbo).
- Assess severity — fires per pixel during PPM colormap processing.
- Coordinate a disclosure date — we are targeting 90 days from first contact.
- We will credit the libjpeg-turbo team in the public disclosure. Preferred acknowledgment format welcome.
Contact: see cover email. This brief is confidential until coordinated disclosure.