djpeg/jpeg_crop_scanline(): Disallow crop vals < 0
Because the crop spec was parsed using unsigned 32-bit integers,
negative numbers were interpreted as values ~= UINT_MAX (4,294,967,295).
This had the following ramifications:
- If the cropping region width was negative and the adjusted width + the
adjusted left boundary was greater than 0, then the 32-bit unsigned
integer bounds checks in djpeg and jpeg_crop_scanline() overflowed and
failed to detect the out-of-bounds width, jpeg_crop_scanline() set
cinfo->output_width to a value ~= UINT_MAX, and a buffer overrun and
subsequent segfault occurred in the upsampling or color conversion
routine. The segfault occurred in the body of
jpeg_skip_scanlines() --> read_and_discard_scanlines() if the cropping
region upper boundary was greater than 0 and the JPEG image used
chrominance subsampling and in the body of jpeg_read_scanlines()
otherwise.
- If the cropping region width was negative and the adjusted width + the
adjusted left boundary was 0, then a zero-width output image was
generated.
- If the cropping region left boundary was negative, then an output
image with bogus data was generated.
This commit modifies djpeg and jpeg_crop_scanline() so that the
aforementioned bounds checks use 64-bit unsigned integers, thus guarding
against overflow. It similarly modifies jpeg_skip_scanlines(). In the
case of jpeg_skip_scanlines(), the issue was not reproducible with
djpeg, but passing a negative number of lines to jpeg_skip_scanlines()
caused a similar overflow if the number of lines +
cinfo->output_scanline was greater than 0. That caused
jpeg_skip_scanlines() to read past the end of the JPEG image, throw a
warning ("Corrupt JPEG data: premature end of data segment"), and fail
to return unless warnings were treated as fatal. Also, djpeg now parses
the crop spec using signed integers and checks for negative values.
This commit is contained in:
10
ChangeLog.md
10
ChangeLog.md
@@ -33,6 +33,16 @@ attempting to generate a full-color lossless JPEG image using the TurboJPEG
|
||||
Java API's `byte[] TJCompressor.compress()` method if the value of
|
||||
`TJ.PARAM_SUBSAMP` was not `TJ.SAMP_444`.
|
||||
|
||||
6. Fixed a segfault in djpeg that occurred if a negative width was specified
|
||||
with the `-crop` option. Since the cropping region width was read into an
|
||||
unsigned 32-bit integer, a negative width was interpreted as a very large
|
||||
value. With certain negative width and positive left boundary values, the
|
||||
bounds checks in djpeg and `jpeg_crop_scanline()` overflowed and did not detect
|
||||
the out-of-bounds width, which caused a buffer overrun in the upsampling or
|
||||
color conversion routine. Both bounds checks now use 64-bit integers to guard
|
||||
against overflow, and djpeg now checks for negative numbers when it parses the
|
||||
crop specification from the command line.
|
||||
|
||||
|
||||
3.0.3
|
||||
=====
|
||||
|
||||
Reference in New Issue
Block a user