Projects
Eulaceura:Mainline:GA
freeimage
_service:obs_scm:CVE-2020-21427-1-r1832-improve...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:CVE-2020-21427-1-r1832-improved-BMP-plugin-when-working-with-malicious-images.patch of Package freeimage
Origin: upstream, r1832 Index: Source/FreeImage/PluginBMP.cpp --- diff --git a/Source/FreeImage/PluginBMP.cpp b/Source/FreeImage/PluginBMP.cpp --- a/Source/FreeImage/PluginBMP.cpp (revision 1831) +++ b/Source/FreeImage/PluginBMP.cpp (revision 1832) @@ -181,6 +181,7 @@ } } #endif + #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB if (bit_count == 24 || bit_count == 32) { for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) { @@ -202,7 +203,7 @@ @param handle FreeImage IO handle @param width Image width @param height Image height -@param dib Image to be loaded +@param dib 4-bit image to be loaded @return Returns TRUE if successful, returns FALSE otherwise */ static BOOL @@ -217,7 +218,9 @@ height = abs(height); pixels = (BYTE*)malloc(width * height * sizeof(BYTE)); - if(!pixels) throw(1); + if (!pixels) { + throw(1); + } memset(pixels, 0, width * height * sizeof(BYTE)); BYTE *q = pixels; @@ -237,7 +240,7 @@ throw(1); } for (int i = 0; i < status_byte; i++) { - *q++=(BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f)); + *q++ = (BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f)); } bits += status_byte; } @@ -252,7 +255,7 @@ // End of line bits = 0; scanline++; - q = pixels + scanline*width; + q = pixels + scanline * width; } break; @@ -264,7 +267,6 @@ case RLE_DELTA: { // read the delta values - BYTE delta_x = 0; BYTE delta_y = 0; @@ -276,7 +278,6 @@ } // apply them - bits += delta_x; scanline += delta_y; q = pixels + scanline*width+bits; @@ -293,7 +294,7 @@ throw(1); } } - *q++=(BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f)); + *q++ = (BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f)); } bits += status_byte; // Read pad byte @@ -334,7 +335,9 @@ return TRUE; } catch(int) { - if(pixels) free(pixels); + if (pixels) { + free(pixels); + } return FALSE; } } @@ -345,7 +348,7 @@ @param handle FreeImage IO handle @param width Image width @param height Image height -@param dib Image to be loaded +@param dib 8-bit image to be loaded @return Returns TRUE if successful, returns FALSE otherwise */ static BOOL @@ -354,103 +357,85 @@ BYTE second_byte = 0; int scanline = 0; int bits = 0; + int count = 0; + BYTE delta_x = 0; + BYTE delta_y = 0; - for (;;) { - if( io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) { + height = abs(height); + + while(scanline < height) { + + if (io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) { return FALSE; } - switch (status_byte) { - case RLE_COMMAND : - if(io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) { - return FALSE; - } + if (status_byte == RLE_COMMAND) { + if (io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) { + return FALSE; + } - switch (status_byte) { - case RLE_ENDOFLINE : - bits = 0; - scanline++; - break; + switch (status_byte) { + case RLE_ENDOFLINE: + bits = 0; + scanline++; + break; - case RLE_ENDOFBITMAP : - return TRUE; + case RLE_ENDOFBITMAP: + return TRUE; - case RLE_DELTA : - { - // read the delta values + case RLE_DELTA: + // read the delta values + delta_x = 0; + delta_y = 0; + if (io->read_proc(&delta_x, sizeof(BYTE), 1, handle) != 1) { + return FALSE; + } + if (io->read_proc(&delta_y, sizeof(BYTE), 1, handle) != 1) { + return FALSE; + } + // apply them + bits += delta_x; + scanline += delta_y; + break; - BYTE delta_x = 0; - BYTE delta_y = 0; - - if(io->read_proc(&delta_x, sizeof(BYTE), 1, handle) != 1) { - return FALSE; - } - if(io->read_proc(&delta_y, sizeof(BYTE), 1, handle) != 1) { - return FALSE; - } - - // apply them - - bits += delta_x; - scanline += delta_y; - - break; + default: + // absolute mode + count = MIN((int)status_byte, width - bits); + if (count < 0) { + return FALSE; } - - default : - { - if(scanline >= abs(height)) { - return TRUE; - } - - int count = MIN((int)status_byte, width - bits); - - BYTE *sline = FreeImage_GetScanLine(dib, scanline); - - if(io->read_proc((void *)(sline + bits), sizeof(BYTE) * count, 1, handle) != 1) { + BYTE *sline = FreeImage_GetScanLine(dib, scanline); + if (io->read_proc((void *)(sline + bits), sizeof(BYTE) * count, 1, handle) != 1) { + return FALSE; + } + // align run length to even number of bytes + if ((status_byte & 1) == 1) { + if (io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) { return FALSE; } - - // align run length to even number of bytes - - if ((status_byte & 1) == 1) { - if(io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) { - return FALSE; - } - } - - bits += status_byte; - - break; } - } + bits += status_byte; + break; - break; - - default : - { - if(scanline >= abs(height)) { - return TRUE; - } - - int count = MIN((int)status_byte, width - bits); - - BYTE *sline = FreeImage_GetScanLine(dib, scanline); - - if(io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) { - return FALSE; - } - - for (int i = 0; i < count; i++) { - *(sline + bits) = second_byte; - - bits++; - } - - break; + } // switch (status_byte) + } + else { + count = MIN((int)status_byte, width - bits); + if (count < 0) { + return FALSE; } + BYTE *sline = FreeImage_GetScanLine(dib, scanline); + if (io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) { + return FALSE; + } + for (int i = 0; i < count; i++) { + *(sline + bits) = second_byte; + bits++; + } } } + + return FALSE; } // -------------------------------------------------------------------------- @@ -463,10 +448,12 @@ BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS; // load the info header - BITMAPINFOHEADER bih; + memset(&bih, 0, sizeof(BITMAPINFOHEADER)); + if (io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle) != 1) { + throw FI_MSG_ERROR_INVALID_FORMAT; + } - io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle); #ifdef FREEIMAGE_BIGENDIAN SwapInfoHeader(&bih); #endif @@ -544,7 +531,7 @@ break; case BI_RLE4 : - if( LoadPixelDataRLE4(io, handle, width, height, dib) ) { + if( (bit_count == 4) && LoadPixelDataRLE4(io, handle, width, height, dib) ) { return dib; } else { throw "Error encountered while decoding RLE4 BMP data"; @@ -552,7 +539,7 @@ break; case BI_RLE8 : - if( LoadPixelDataRLE8(io, handle, width, height, dib) ) { + if( (bit_count == 8) && LoadPixelDataRLE8(io, handle, width, height, dib) ) { return dib; } else { throw "Error encountered while decoding RLE8 BMP data"; @@ -602,7 +589,7 @@ return dib; } - break; // 16-bit + break; // 16-bit RGB case 24 : case 32 : @@ -679,10 +666,12 @@ BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS; // load the info header - BITMAPINFOHEADER bih; + memset(&bih, 0, sizeof(BITMAPINFOHEADER)); + if (io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle) != 1) { + throw FI_MSG_ERROR_INVALID_FORMAT; + } - io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle); #ifdef FREEIMAGE_BIGENDIAN SwapInfoHeader(&bih); #endif @@ -767,17 +756,19 @@ return dib; case BI_RLE4 : - if( LoadPixelDataRLE4(io, handle, width, height, dib) ) { + if ((bit_count == 4) && LoadPixelDataRLE4(io, handle, width, height, dib)) { return dib; - } else { + } + else { throw "Error encountered while decoding RLE4 BMP data"; } break; case BI_RLE8 : - if( LoadPixelDataRLE8(io, handle, width, height, dib) ) { + if ((bit_count == 8) && LoadPixelDataRLE8(io, handle, width, height, dib)) { return dib; - } else { + } + else { throw "Error encountered while decoding RLE8 BMP data"; } break; @@ -863,9 +854,9 @@ } } } catch(const char *message) { - if(dib) + if (dib) { FreeImage_Unload(dib); - + } FreeImage_OutputMessageProc(s_format_id, message); } @@ -881,9 +872,13 @@ try { BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS; + // load the info header BITMAPINFOOS2_1X_HEADER bios2_1x; + memset(&bios2_1x, 0, sizeof(BITMAPINFOOS2_1X_HEADER)); + if (io->read_proc(&bios2_1x, sizeof(BITMAPINFOOS2_1X_HEADER), 1, handle) != 1) { + throw FI_MSG_ERROR_INVALID_FORMAT; + } - io->read_proc(&bios2_1x, sizeof(BITMAPINFOOS2_1X_HEADER), 1, handle); #ifdef FREEIMAGE_BIGENDIAN SwapOS21XHeader(&bios2_1x); #endif @@ -1005,9 +1000,9 @@ } } } catch(const char *message) { - if(dib) + if (dib) { FreeImage_Unload(dib); - + } FreeImage_OutputMessageProc(s_format_id, message); } @@ -1090,19 +1085,20 @@ BITMAPFILEHEADER bitmapfileheader; DWORD type = 0; - // we use this offset value to make seemingly absolute seeks relative in the file - + // we use this offset value to make seemingly absolute seeks relative in the file long offset_in_file = io->tell_proc(handle); // read the fileheader + memset(&bitmapfileheader, 0, sizeof(BITMAPFILEHEADER)); + if (io->read_proc(&bitmapfileheader, sizeof(BITMAPFILEHEADER), 1, handle) != 1) { + return NULL; + } - io->read_proc(&bitmapfileheader, sizeof(BITMAPFILEHEADER), 1, handle); #ifdef FREEIMAGE_BIGENDIAN SwapFileHeader(&bitmapfileheader); #endif // check the signature - if((bitmapfileheader.bfType != 0x4D42) && (bitmapfileheader.bfType != 0x4142)) { FreeImage_OutputMessageProc(s_format_id, FI_MSG_ERROR_MAGIC_NUMBER); return NULL; @@ -1109,9 +1105,9 @@ } // read the first byte of the infoheader - io->read_proc(&type, sizeof(DWORD), 1, handle); io->seek_proc(handle, 0 - (long)sizeof(DWORD), SEEK_CUR); + #ifdef FREEIMAGE_BIGENDIAN SwapLong(&type); #endif @@ -1138,7 +1134,7 @@ break; } - FreeImage_OutputMessageProc(s_format_id, "unknown bmp subtype with id %d", type); + FreeImage_OutputMessageProc(s_format_id, "Unknown bmp subtype with id %d", type); } return NULL; @@ -1418,6 +1414,7 @@ } free(buffer); + #ifdef FREEIMAGE_BIGENDIAN } else if (dst_bpp == 16) { int padding = dst_pitch - dst_width * sizeof(WORD); @@ -1439,6 +1436,7 @@ } } #endif + #if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB } else if (dst_bpp == 24) { int padding = dst_pitch - dst_width * sizeof(FILE_BGR);
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2