port upstream fix for local buffer overflow

r1425

Fix Huffman local buffer overrun discovered by Debian developers when
attempting to transform a junk image using ImageMagick:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=768369
This commit is contained in:
Antony Dovgal
2014-12-16 13:52:33 +03:00
parent fa01dcb519
commit a06aeb25f2
2 changed files with 22 additions and 1 deletions

View File

@@ -16,6 +16,18 @@ instead of -1 if width was < 1.
[8] cjpeg, djpeg, and jpegtran now accept an argument of -version, which will
print the library version and exit.
[9] Referring to 1.4 beta1 [15], another extremely rare circumstance was
discovered under which the Huffman encoder's local buffer can be overrun
when a buffered destination manager is being used and an
extremely-high-frequency block (basically junk image data) is being encoded.
Even though the Huffman local buffer was increased from 128 bytes to 136 bytes
to address the previous issue, the new issue caused even the larger buffer to
be overrun. Further analysis reveals that, in the absolute worst case (such as
setting alternating AC coefficients to 32767 and -32768 in the JPEG scanning
order), the Huffman encoder can produce encoded blocks that approach double the
size of the unencoded blocks. Thus, the Huffman local buffer was increased to
256 bytes, which should prevent any such issue from re-occurring in the future.
1.3.90 (1.4 beta1)
==================

View File

@@ -408,7 +408,16 @@ dump_buffer (working_state * state)
#endif
#define BUFSIZE (DCTSIZE2 * 2) + 8
/* Although it is exceedingly rare, it is possible for a Huffman-encoded
* coefficient block to be larger than the 128-byte unencoded block. For each
* of the 64 coefficients, PUT_BITS is invoked twice, and each invocation can
* theoretically store 16 bits (for a maximum of 2048 bits or 256 bytes per
* encoded block.) If, for instance, one artificially sets the AC
* coefficients to alternating values of 32767 and -32768 (using the JPEG
* scanning order-- 1, 8, 16, etc.), then this will produce an encoded block
* larger than 200 bytes.
*/
#define BUFSIZE (DCTSIZE2 * 4)
#define LOAD_BUFFER() { \
if (state->free_in_buffer < BUFSIZE) { \