In late 2013, a critical security issue was uncovered affecting the widely used libjpeg and libjpeg-turbo libraries. These libraries are fundamental in handling JPEG images and are utilized by many prominent software including Google Chrome (before version 31..165.48), Ghostscript, and lots of desktop/mobile applications. Let’s explore CVE-2013-6629: how it works, what the exploit looks like, and why it’s a textbook example of a classic C programming pitfall.

What Happened?

CVE-2013-6629 refers to an information disclosure vulnerability in the get_sos function found in the jdmarker.c file of (1) libjpeg version 6b and (2) libjpeg-turbo up to 1.3.. The vulnerability arises because the code fails to check for duplicate JPEG component data in segments that follow the Start Of Scan (SOS) JPEG marker. As a result, a maliciously crafted JPEG can cause applications to leak pieces of uninitialized memory (possibly containing confidential information) when decoding a JPEG.

Why is This Bad?

Uninitialized memory can contain pretty much anything: random data left on the stack or heap, bits of other images, passwords, login tokens, or even cryptographic secrets, depending on what else your app is doing. If a crafted image finds its way into your email, web browser, or PDF reader, you *might* be leaking sensitive data to the attacker.

How Does JPEG and SOS Work?

In JPEG images, the SOS ("Start of Scan") marker tells the decoder where the actual image data begins. The JPEG spec says that every image must describe its components in a certain way, and each component must be listed only once.

The bug: The vulnerable code didn't verify that each component was only listed once — it just iterated over whatever the image supplied.

Here’s the problematic function, simplified

// Vulnerable: libjpeg jdmarker.c - get_sos()
for (i = ; i < n; i++) {
    int cc = read_1_byte();
    int c = ;
    for (j = ; j < cinfo->comps_in_scan; j++)     // <--- No duplication check!
        if (cc == cinfo->cur_comp_info[j]->component_id)
            c = 1;
    cinfo->cur_comp_info[i] = curcomp;
}

What's missing?

It should check for duplicates each time a new component is being added!

What Could Happen?

If a JPEG lists a component twice, the second entry would reference uninitialized memory. When the decoder later processes this information (which includes writing the output/decoded image), it would include leftover garbage from memory — possibly leaking data.

Practical Exploit Example

An attacker-crafted JPEG can be made with duplicate components after the SOS marker. When a victim app opens this image, it might spew bytes from memory straight into the decoded bitmap. An attacker who receives this bitmap could analyze the "noisy" pixels and extract bits of private memory.

Victim: Opens the image with vulnerable software (e.g., pre-31 Chrome, Ghostscript).

3. Victim Software: Decodes the JPEG, allocates a structure for each supposed component, but one or more point at random (uninitialized) memory.

Minimal Exploit JPEG Structure

Below is a rough hand-crafted JPEG segment (not a full image!), showing where the duplication could be:

FF D8             ; SOI (Start of Image)
FF C [...]       ; SOF (Start of Frame)
FF DA             ; SOS (Start of Scan)
03                ; Number of components in scan (e.g., 3)
01 00             ; Component 1, table 
01 00             ; Component 1 AGAIN, table   <-- duplication!
01 00             ; Component 1 AGAIN, table   <-- more duplication!
[...]
FF D9             ; EOI (End of Image)

When viewed, this could pull memory from other parts of the process and present it as image data.

Ghostscript

- Many other apps/browsers/images libraries embedding affected libjpeg versions at the time

Fix and Mitigation

The fix is pretty simple: add a check to ensure each component appears only once. Here’s the kind of logic added:

// Fixed: Check for duplicate components
for (i = ; i < n; i++) {
    int cc = read_1_byte();
    for (j = ; j < i; j++) {
        if (cc == cinfo->cur_comp_info[j]->component_id)
            ERREXIT(cinfo, "Duplicate component in SOS");
    }
    // process as usual...
}

Browser vendors and upstream maintainers released patched versions quickly after discovery.

References

- NVD CVE-2013-6629
- Google Chrome Issue 306215
- libjpeg-turbo security advisory
- Ghostscript Security Issue
- Red Hat Bugzilla - 1071485

Summary

CVE-2013-6629 is a vivid example of how minor oversights in C programming — especially when dealing with untrusted input and memory — can escalate into critical security vulnerabilities. If your software handles images, make sure your JPEG library is up to date! Never trust unvalidated data, even in “just images.”

Timeline

Published on: 11/19/2013 04:50:56 UTC
Last modified on: 11/25/2025 17:50:16 UTC