1.FreeImage-3.18 LibOpenJpeg/j2k.c file memcpy function Out-of-bounds
A out-of-bounds in line '3643' of the 'j2k_read_ppm_v3' function. Where the value of 'l_N_ppm' comes from the file read in, and occurs out-of-bounds when 'l_N_ppm' is greater than the size of p_header_data.
2.FreeImage-3.18 PluginTIFF.cpp file load function heap overflow vulnerability
When the program reads a tiff file, it will be handed to the Load function of the 'PluginTIFF.cpp' file, but in the '2074' line of the program, when the 'memcpy' function is executed, the destination address and the size of the copied data are not considered, resulting in heap overflow.
In the code above, we can see that 'dst_bits' comes from 'bits+rowSize' , In first round of the loop , the 'rowSize' is 0 , so the value of 'dst_bits' is the bits, and the bits is the return pointer of the 'FreeImage_GetScanLine' function
When the 'height' parameter is 1 , we see that the actual returned pointer is the return value of the 'FreeImage_GetBits' function
However,when I look at the documentation and the code of the 'FreeImage_GetBits' function, I still don't find that the returned pointer has a complete stack structure. Which makes dst_bits is like a magic address.
In fact, it is found through debugging that this address is in the heap space , but when the src_line is large enough, it will cause the coverage of the adjacent heap.
The sample of the crash is in the attachment, the name is heap-buff-overflow.tiff
3.A stack buff overflower on line 1284 at PluginTIFF.cpp
When reading a tiff file, the program will call the load function in 'PluginTIFF.cpp', In the '2251' line of the 'load' function, the program will call the 'ReadThumbnail' function.
Entering the 'ReadThumbnail' function, we see that the 'load' function is called again on line '1288'. However, the decision to determine the recursion is based on the return value of the 'TIFFSetSubDirectory' function.
In fact, the function that determines the return value of TIFFSetSubDirectory is the result of the 'TIFFReadDirectory' function.But under some special conditions, the 'TIFFReadDirectory' function always returns 1, which will cause the program stack space to be filled.
The following is a concrete example, which causes program memory corruption, which can lead to remote denial of service by attackers.
The sample of the crash is in the attachment, the name is stack-overflow.tiff
When reading a special JXR file, the 249 line StreamCalcIFDSize function of JXRMeta.c repeatedly calls itself due to improper processing of the file, eventually causing the stack to be filled.An attacker can reach a remote denial of service attack by sending a specially constructed file.
The following example is the status of the stack space after the crash is triggered.
This portion of code copies image data from a libTIFF-provided buffer to an
internal buffer. The overflow happens because src_line is larger than the
size of dst_bits.
This is the result of an inconsistency between libTIFF and freeimage:
In the freeimage case, tile row size is
bitsperpixel * tilewidth / 8
= 32 * 7 / 8 = 28
As a result, the two buffers are differently sized.
freeimage has a bpp of 32 because CreateImageType calls
FreeImage_AllocateHeader with MIN(bpp, 32).
This 'MIN(bpp, 32)' looks like a terrible hack to me, but we can't change
it to 'bpp' because FIT_BITMAP images with bpp > 32 does not seem to be
supported by freeimage. Also, in this case, bpp > 32 doesn't even make
sense:
Looking closely at the reproducer, we can notice that it defines a bilevel
image with samplesperpixel and bitspersample parameters, both unexpected in
bilevel images.
Pixels in bilevel images can either be black or white. There is as such
only one sample per pixel, and a single bit per sample is sufficient. The
spec defines bpp = 8. It is unclear whether the specification allows for
arbitrary values of bitspersample or samplesperpixel (extrasamples?) in
this case.
This file gets rejected by most libTIFF tools.
patch
add check to CreateImageType() to reject FIT_BITMAP images with bpp > 32
instead of passing MIN(bpp, 32).
change type of dst_pitch to unsigned
call memcpy with MIN(dst_pitch, src_line) instead of src_line. this will
help overcome any further (future) discrepancy between libTIFF and
freeimage.
I seem to have run into this issue with freeimage not being able to handle bpp over 32;
I have a dng photo that I try to convert to grayscale. I can provide a sample dng photo that seems to cause freeimage to fail.
I created a mailing list issue but no replies as of yet:
FIBITMAP*fi_bitmap=FreeImage_Load(format, path);if(fi_bitmap==nullptr) {
returnfalse;
}
intbpp=FreeImage_GetBPP(fi_bitmap);thisreturns48FIBITMAP*gs_bitmap=FreeImage_ConvertToGreyscale(fi_bitmap);bpp=FreeImage_GetBPP(gs_bitmap); //at this point it returns 0
Why is this call failing? I am working with an adobe dng file.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
1.FreeImage-3.18 LibOpenJpeg/j2k.c file memcpy function Out-of-bounds
A out-of-bounds in line '3643' of the 'j2k_read_ppm_v3' function. Where the value of 'l_N_ppm' comes from the file read in, and occurs out-of-bounds when 'l_N_ppm' is greater than the size of p_header_data.
2.FreeImage-3.18 PluginTIFF.cpp file load function heap overflow vulnerability
When the program reads a tiff file, it will be handed to the Load function of the 'PluginTIFF.cpp' file, but in the '2074' line of the program, when the 'memcpy' function is executed, the destination address and the size of the copied data are not considered, resulting in heap overflow.
In the code above, we can see that 'dst_bits' comes from 'bits+rowSize' , In first round of the loop , the 'rowSize' is 0 , so the value of 'dst_bits' is the bits, and the bits is the return pointer of the 'FreeImage_GetScanLine' function
When the 'height' parameter is 1 , we see that the actual returned pointer is the return value of the 'FreeImage_GetBits' function
However,when I look at the documentation and the code of the 'FreeImage_GetBits' function, I still don't find that the returned pointer has a complete stack structure. Which makes dst_bits is like a magic address.
In fact, it is found through debugging that this address is in the heap space , but when the src_line is large enough, it will cause the coverage of the adjacent heap.
The sample of the crash is in the attachment, the name is heap-buff-overflow.tiff
3.A stack buff overflower on line 1284 at PluginTIFF.cpp
When reading a tiff file, the program will call the load function in 'PluginTIFF.cpp', In the '2251' line of the 'load' function, the program will call the 'ReadThumbnail' function.
Entering the 'ReadThumbnail' function, we see that the 'load' function is called again on line '1288'. However, the decision to determine the recursion is based on the return value of the 'TIFFSetSubDirectory' function.
In fact, the function that determines the return value of TIFFSetSubDirectory is the result of the 'TIFFReadDirectory' function.But under some special conditions, the 'TIFFReadDirectory' function always returns 1, which will cause the program stack space to be filled.
The following is a concrete example, which causes program memory corruption, which can lead to remote denial of service by attackers.
The sample of the crash is in the attachment, the name is stack-overflow.tiff
Last edit: taolaw 2019-05-19
@taolaw the first issue was seemingly found using a very old release of openjpeg (prior https://github.com/uclouvain/openjpeg/commit/c887df12a38ff1a2721d0c8a93b74fe1d02701a2).
Can you please provide a reproducer for this?
4.A stack buff overflower in JXRMeta.c
When reading a special
JXR file
, the249
lineStreamCalcIFDSize
function ofJXRMeta.c
repeatedly calls itself due to improper processing of the file, eventually causing the stack to be filled.An attacker can reach a remote denial of service attack by sending a specially constructed file.The following example is the status of the stack space after the crash is triggered.
Regarding overflow No. 2.
From the Debian bug report:
You can find the patch in attachment.
Last edit: Hugo Lefeuvre 2019-11-03
I seem to have run into this issue with freeimage not being able to handle bpp over 32;
I have a dng photo that I try to convert to grayscale. I can provide a sample dng photo that seems to cause freeimage to fail.
I created a mailing list issue but no replies as of yet:
Why is this call failing? I am working with an adobe dng file.
I believe [1] adresses CVE-2019-12211 (nr 2 above) and CVE-2019-12213 (nr 3 above)
[1] https://sourceforge.net/p/freeimage/svn/1825/tree//FreeImage/trunk/Source/FreeImage/PluginTIFF.cpp?diff=5a0ca8dd5a4a1f6b3942a079:1824
@sandromani thanks for the heads-up. [r1825] is indeed a modified version of my patch proposal.
Related
Commit: [r1825]
Aret here any fixes for CVE-2019-12212 and CVE-2019-12214?