diff --git a/CVE-2019-12211_2019-12213.patch b/CVE-2019-12211_2019-12213.patch new file mode 100644 index 0000000..61a7a98 --- /dev/null +++ b/CVE-2019-12211_2019-12213.patch @@ -0,0 +1,183 @@ +diff -rupN --no-dereference FreeImage/Source/FreeImage/PluginTIFF.cpp FreeImage-new/Source/FreeImage/PluginTIFF.cpp +--- FreeImage/Source/FreeImage/PluginTIFF.cpp 2019-11-17 14:18:12.447058346 +0100 ++++ FreeImage-new/Source/FreeImage/PluginTIFF.cpp 2019-11-17 14:18:12.630057689 +0100 +@@ -122,9 +122,14 @@ static void ReadThumbnail(FreeImageIO *i + static int s_format_id; + + typedef struct { ++ //! FreeImage IO functions + FreeImageIO *io; ++ //! FreeImage handle + fi_handle handle; ++ //! LibTIFF handle + TIFF *tif; ++ //! Count the number of thumbnails already read (used to avoid recursion on loading) ++ unsigned thumbnailCount; + } fi_TIFFIO; + + // ---------------------------------------------------------- +@@ -184,10 +189,8 @@ Open a TIFF file descriptor for reading + */ + TIFF * + TIFFFdOpen(thandle_t handle, const char *name, const char *mode) { +- TIFF *tif; +- + // Open the file; the callback will set everything up +- tif = TIFFClientOpen(name, mode, handle, ++ TIFF *tif = TIFFClientOpen(name, mode, handle, + _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, + _tiffSizeProc, _tiffMapProc, _tiffUnmapProc); + +@@ -449,12 +452,10 @@ CreateImageType(BOOL header_only, FREE_I + } + + } +- else { +- +- dib = FreeImage_AllocateHeader(header_only, width, height, MIN(bpp, 32), FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK); ++ else if (bpp <= 32) { ++ dib = FreeImage_AllocateHeader(header_only, width, height, bpp, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK); + } + +- + } else { + // other bitmap types + +@@ -1039,9 +1040,12 @@ static void * DLL_CALLCONV + Open(FreeImageIO *io, fi_handle handle, BOOL read) { + // wrapper for TIFF I/O + fi_TIFFIO *fio = (fi_TIFFIO*)malloc(sizeof(fi_TIFFIO)); +- if(!fio) return NULL; ++ if (!fio) { ++ return NULL; ++ } + fio->io = io; + fio->handle = handle; ++ fio->thumbnailCount = 0; + + if (read) { + fio->tif = TIFFFdOpen((thandle_t)fio, "", "r"); +@@ -1097,6 +1101,27 @@ check for uncommon bitspersample values + */ + static BOOL + IsValidBitsPerSample(uint16 photometric, uint16 bitspersample, uint16 samplesperpixel) { ++ // get the pixel depth in bits ++ const uint16 pixel_depth = bitspersample * samplesperpixel; ++ ++ // check for a supported pixel depth ++ switch (pixel_depth) { ++ case 1: ++ case 4: ++ case 8: ++ case 16: ++ case 24: ++ case 32: ++ case 48: ++ case 64: ++ case 96: ++ case 128: ++ // OK, go on ++ break; ++ default: ++ // unsupported pixel depth ++ return FALSE; ++ } + + switch(bitspersample) { + case 1: +@@ -1137,6 +1162,8 @@ IsValidBitsPerSample(uint16 photometric, + default: + return FALSE; + } ++ ++ return FALSE; + } + + static TIFFLoadMethod +@@ -1226,15 +1253,30 @@ Read embedded thumbnail + static void + ReadThumbnail(FreeImageIO *io, fi_handle handle, void *data, TIFF *tiff, FIBITMAP *dib) { + FIBITMAP* thumbnail = NULL; +- ++ ++ fi_TIFFIO *fio = (fi_TIFFIO*)data; ++ ++ /* ++ Thumbnail loading can cause recursions because of the way ++ functions TIFFLastDirectory and TIFFSetSubDirectory are working. ++ We use here a hack to count the number of times the ReadThumbnail function was called. ++ We only allow one call, check for this ++ */ ++ if (fio->thumbnailCount > 0) { ++ return; ++ } ++ else { ++ // update the thumbnail count (used to avoid recursion) ++ fio->thumbnailCount++; ++ } ++ + // read exif thumbnail (IFD 1) ... + +- /* +- // this code can cause unwanted recursion causing an overflow, it is thus disabled until we have a better solution +- // do we really need to read a thumbnail from the Exif segment ? knowing that TIFF store the thumbnail in the subIFD ... +- // + toff_t exif_offset = 0; + if(TIFFGetField(tiff, TIFFTAG_EXIFIFD, &exif_offset)) { ++ ++ // this code can cause unwanted recursion causing an overflow, because of the way TIFFLastDirectory work ++ // => this is checked using + + if(!TIFFLastDirectory(tiff)) { + // save current position +@@ -1245,15 +1287,15 @@ ReadThumbnail(FreeImageIO *io, fi_handle + int page = 1; + int flags = TIFF_DEFAULT; + thumbnail = Load(io, handle, page, flags, data); ++ + // store the thumbnail (remember to release it before return) + FreeImage_SetThumbnail(dib, thumbnail); +- ++ + // restore current position + io->seek_proc(handle, tell_pos, SEEK_SET); + TIFFSetDirectory(tiff, cur_dir); + } + } +- */ + + // ... or read the first subIFD + +@@ -1270,11 +1312,14 @@ ReadThumbnail(FreeImageIO *io, fi_handle + const long tell_pos = io->tell_proc(handle); + const uint16 cur_dir = TIFFCurrentDirectory(tiff); + ++ // this code can cause unwanted recursion causing an overflow, because of the way TIFFSetSubDirectory work ++ + if(TIFFSetSubDirectory(tiff, subIFD_offsets[0])) { + // load the thumbnail + int page = -1; + int flags = TIFF_DEFAULT; + thumbnail = Load(io, handle, page, flags, data); ++ + // store the thumbnail (remember to release it before return) + FreeImage_SetThumbnail(dib, thumbnail); + } +@@ -2030,7 +2075,7 @@ Load(FreeImageIO *io, fi_handle handle, + } + + // calculate src line and dst pitch +- int dst_pitch = FreeImage_GetPitch(dib); ++ unsigned dst_pitch = FreeImage_GetPitch(dib); + uint32 tileRowSize = (uint32)TIFFTileRowSize(tif); + uint32 imageRowSize = (uint32)TIFFScanlineSize(tif); + +@@ -2060,7 +2105,7 @@ Load(FreeImageIO *io, fi_handle handle, + BYTE *src_bits = tileBuffer; + BYTE *dst_bits = bits + rowSize; + for(int k = 0; k < nrows; k++) { +- memcpy(dst_bits, src_bits, src_line); ++ memcpy(dst_bits, src_bits, MIN(dst_pitch, src_line)); + src_bits += tileRowSize; + dst_bits -= dst_pitch; + } diff --git a/FreeImage3180.zip b/FreeImage3180.zip new file mode 100644 index 0000000..c25d666 Binary files /dev/null and b/FreeImage3180.zip differ diff --git a/freeimage.spec b/freeimage.spec new file mode 100644 index 0000000..fa6d1e2 --- /dev/null +++ b/freeimage.spec @@ -0,0 +1,75 @@ +#%global debug_package %{nil} + +Name: freeimage +Version: 3.18.0 +Release: 1 +Summary: FreeImage is a library project for developers who would like to support popular graphics image formats (PNG, JPEG, TIFF, BMP and others) +License: GPLv2 or GPLv3 and FIPL +URL: https://freeimage.sourceforge.io/ +Source0: http://downloads.sourceforge.net/freeimage/FreeImage3180.zip + +Patch0: CVE-2019-12211_2019-12213.patch + +BuildRequires: gcc autoconf automake doxygen + +%description +FreeImage is a library project for developers who would like to support popular graphics image formats (PNG, JPEG, TIFF, BMP and others). Some highlights are: extremely simple in use, not limited to the local PC (unique FreeImageIO) and Plugin driven! + +%package devel +Summary: FreeImage is a library project for developers who would like to support popular graphics image formats (PNG, JPEG, TIFF, BMP and others) +Requires: %{name} = %{version}-%{release} +%description devel +FreeImage is a library project for developers who would like to support popular graphics image formats (PNG, JPEG, TIFF, BMP and others). Some highlights are: extremely simple in use, not limited to the local PC (unique FreeImageIO) and Plugin driven! + +%prep +%setup -q -n FreeImage +%patch0 -p1 + +%build +%make_build -f Makefile.gnu DESTDIR=%{buildroot} +%make_build -f Makefile.fip DESTDIR=%{buildroot} + +pushd Wrapper/FreeImagePlus/doc +doxygen FreeImagePlus.dox +popd + + +%install +install -Dpm 755 Dist/lib%{name}-%{version}.so %{buildroot}%{_libdir}/lib%{name}-%{version}.so +ln -s lib%{name}-%{version}.so %{buildroot}%{_libdir}/lib%{name}.so + +install -Dpm 755 Dist/lib%{name}plus-%{version}.so %{buildroot}%{_libdir}/lib%{name}plus-%{version}.so +ln -s lib%{name}plus-%{version}.so %{buildroot}%{_libdir}/lib%{name}plus.so +install -Dpm 644 Source/FreeImage.h %{buildroot}%{_includedir}/FreeImage.h +install -Dpm 644 Wrapper/FreeImagePlus/FreeImagePlus.h %{buildroot}%{_includedir}/FreeImagePlus.h + +# install missing symlink (was giving no-ldconfig-symlink rpmlint errors) +ldconfig -n %{buildroot}%{_libdir} + +%pre +%preun +%post +%postun + +%check + +%files +%license license-*.txt +%doc README.linux README.md Whatsnew.txt +%{_libdir}/lib%{name}-%{version}.so +%{_libdir}/lib%{name}.so.* +%{_libdir}/lib%{name}plus-%{version}.so +%{_libdir}/lib%{name}plus.so.* + +%files devel +%doc Examples Wrapper/FreeImagePlus/html +%{_includedir}/FreeImage.h +%{_libdir}/lib%{name}.so +%{_includedir}/FreeImagePlus.h +%{_libdir}/lib%{name}plus.so + + +%changelog +* Mon May 4 2020 Wei Xiong +- Package init +