JPEG Restart Markers and Memory Corruption Risks

This article examines whether malformed or invalid restart marker sequences can trigger memory corruption in JPEG decoders. While JPEG restart markers are intentionally designed to isolate transmission errors and aid in stream resynchronization, flawed parser implementations, unvalidated state transitions, and arithmetic calculation errors in handling these markers can directly lead to vulnerabilities such as heap buffer overflows, out-of-bounds writes, and use-after-free conditions.

Understanding JPEG Restart Markers

In baseline JPEG compression, the image data is segmented into Minimum Coded Units (MCUs). The entropy-coded bitstream (using Huffman or arithmetic coding) makes each block dependent on preceding DC coefficient predictions. To prevent a single bit error from corrupting an entire image, the JPEG standard allows the insertion of restart markers (designated RST0 through RST7, byte values 0xFFD0 through 0xFFD7).

Restart markers appear at regular intervals defined by the Define Restart Interval (DRI) marker. When an RST marker appears, the decoder:

  1. Resets DC coefficient predictors to zero.
  2. Resets the internal entropy decoding state (e.g., bit alignment and Huffman state machine).
  3. Resynchronizes decoding to start cleanly at the next MCU boundary.

Mechanisms Leading to Memory Corruption

Invalid restart markers themselves are just bytes in a stream; memory corruption occurs entirely due to implementation vulnerabilities within the decoder handling that stream. When a sequence is invalid—such as an out-of-order marker, an unexpected marker inside an MCU, or a marker appearing after the designated MCU count has completed—flawed decoders can fail in several distinct ways:

1. Buffer Overflows via Desynchronized MCU Counters

Decoders allocate destination buffers for reconstructed coefficient blocks or decoded pixel rows based on dimensions found in the Frame Header (SOF0). The decoder relies on an internal counter to track the current MCU position across image coordinates.

If an unexpected RST marker arrives and forces the decoder to skip blocks or reset position coordinates incorrectly without bounds checking, the internal write pointer can advance beyond the allocated buffer boundaries. Similarly, if the decoder assumes that an RST marker guarantees a specific number of remaining MCUs, a crafted image containing surplus RST sequences can trick the write loop into continuing past the end of the memory buffer, causing a heap-based buffer overflow.

2. Entropy Decoder State Misalignment

The transition between variable-length coded data and byte-aligned markers requires careful handling of internal bit-buffers. When an RST sequence is encountered, decoders discard leftover bits to realign with a byte boundary.

If a decoder encounters an invalid or misplaced marker and enters an unhandled error state, it may fail to refresh the bit-buffer properly. Reading from an exhausted or desynchronized bit-buffer can cause the entropy decoder to interpret subsequent bytes as invalid run-lengths or high-frequency coefficients, which can lead to negative index calculations or out-of-bounds writes in quantization and inverse discrete cosine transform (IDCT) staging arrays.

3. Premature Scan Termination and Uninitialized Reads

An invalid or duplicated restart sequence might trick a decoder into terminating a scan prematurely while still considering the operation successful. Subsequent processing steps, such as color conversion, upsampling, or post-processing filters, may then operate on uninitialized heap memory. While predominantly an information disclosure risk, reading uninitialized pointer arrays or structure offsets derived from corrupted scan data can lead to arbitrary write primitives or control flow hijacking.

4. Logic Flaws in Marker Emulation Avoidance

The JPEG standard uses byte stuffing (appending 0x00 after any 0xFF data byte) to prevent compressed payload data from being interpreted as a marker. If a parser improperly validates stuffed bytes or encounters an invalid sequence (e.g., 0xFF followed by an invalid marker code instead of 0x00), it may miscalculate stream offsets. An off-by-one error during offset recalculation can trigger out-of-bounds reads or writes during stream buffering operations.

Real-World Relevance

Historically, memory corruption vulnerabilities in image decoders (such as libjpeg, libjpeg-turbo, and proprietary platform decoders) have frequently stemmed from marker parsing logic rather than the mathematical IDCT stages. While modern production-grade libraries employ defensive decoding—treating invalid RST sequences as non-fatal warnings or strictly aborting the scan—embedded decoders, legacy software, and custom parsing engines frequently exhibit unsafe memory operations when processing maliciously crafted sequences.

Mitigation

To prevent memory corruption caused by invalid restart markers: