Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:kernel-2.6.32
lcms
lcms-bnc479606.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File lcms-bnc479606.patch of Package lcms
--- lcms-1.17/include/lcms.h +++ lcms-1.18/include/lcms.h @@ -1415,6 +1415,14 @@ return (void*) malloc(size); } +LCMS_INLINE void* _cmsCalloc(size_t nmemb, size_t size) +{ + size_t alloc = nmemb * size; + if (alloc < nmemb || alloc < size) { + return NULL; + } + return _cmsMalloc(alloc); +} LCMS_INLINE void _cmsFree(void *Ptr) { @@ -2027,6 +2035,10 @@ // Build a tone curve for K->K' if possible (only works on CMYK) LPGAMMATABLE _cmsBuildKToneCurve(cmsHTRANSFORM hCMYK2CMYK, int nPoints); +// Validates a LUT +LCMSBOOL cdecl _cmsValidateLUT(LPLUT NewLUT); + + // These are two VITAL macros, from converting between 8 and 16 bit // representation. --- lcms-1.17/src/cmsgamma.c +++ lcms-1.18/src/cmsgamma.c @@ -114,7 +114,7 @@ LPGAMMATABLE p; size_t size; - if (nEntries > 65530 || nEntries < 0) { + if (nEntries > 65530 || nEntries <= 0) { cmsSignalError(LCMS_ERRC_ABORTED, "Couldn't create gammatable of more than 65530 entries"); return NULL; } --- lcms-1.17/src/cmsio0.c +++ lcms-1.18/src/cmsio0.c @@ -33,7 +33,7 @@ typedef struct { LPBYTE Block; // Points to allocated memory size_t Size; // Size of allocated memory - int Pointer; // Points to current location + size_t Pointer; // Points to current location int FreeBlockOnClose; // As title } FILEMEM; @@ -75,7 +75,17 @@ FILEMEM* ResData = (FILEMEM*) Icc ->stream; LPBYTE Ptr; size_t len = size * count; + size_t extent = ResData -> Pointer + len; + if (len < size || len < count) { + cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Integer overflow with count / size."); + return 0; + } + + if (extent < len || extent < ResData -> Pointer) { + cmsSignalError(LCMS_ERRC_ABORTED, "Read from memory error. Integer overflow with len."); + return 0; + } if (ResData -> Pointer + len > ResData -> Size){ --- lcms-1.17/src/cmsio1.c +++ lcms-1.18/src/cmsio1.c @@ -261,11 +261,14 @@ // Read profile header and validate it static -LPLCMSICCPROFILE ReadHeader(LPLCMSICCPROFILE Icc, LCMSBOOL lIsFromMemory) +LPLCMSICCPROFILE ReadHeader(LPLCMSICCPROFILE Icc, + LCMSBOOL lIsFromMemory, + DWORD dwSize) { icTag Tag; icHeader Header; icInt32Number TagCount, i; + icUInt32Number extent; if (Icc -> Read(&Header, sizeof(icHeader), 1, Icc) != 1) goto ErrorCleanup; @@ -287,6 +290,10 @@ if (Header.magic != icMagicNumber) goto ErrorCleanup; + if (dwSize && dwSize != Header.size) { + goto ErrorCleanup; + } + if (Icc ->Read(&TagCount, sizeof(icInt32Number), 1, Icc) != 1) goto ErrorCleanup; @@ -321,7 +328,7 @@ // Read tag directory - if (TagCount > MAX_TABLE_TAG) { + if (TagCount > MAX_TABLE_TAG || TagCount < 0) { cmsSignalError(LCMS_ERRC_ABORTED, "Too many tags (%d)", TagCount); goto ErrorCleanup; @@ -338,8 +345,9 @@ AdjustEndianess32((LPBYTE) &Tag.sig); // Signature // Perform some sanity check. Offset + size should fall inside file. - - if (Tag.offset + Tag.size > Header.size) goto ErrorCleanup; + extent = Tag.offset + Tag.size; + if (extent > Header.size || extent < Tag.offset) + goto ErrorCleanup; Icc -> TagNames[i] = Tag.sig; Icc -> TagOffsets[i] = Tag.offset; @@ -494,9 +502,9 @@ NewLUT -> OutputEntries = 256; // Do some checking - if (NewLUT -> cLutPoints > 100) NewLUT ->cLutPoints = 100; - if (NewLUT -> InputChan > MAXCHANNELS) NewLUT -> InputChan = MAXCHANNELS; - if (NewLUT -> OutputChan > MAXCHANNELS) NewLUT -> OutputChan = MAXCHANNELS; + if (!_cmsValidateLUT(NewLUT)) { + return FALSE; + } AdjustEndianess32((LPBYTE) &LUT8.e00); AdjustEndianess32((LPBYTE) &LUT8.e01); @@ -571,7 +579,7 @@ if (nTabSize > 0) { - PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * nTabSize); + PtrW = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize); if (PtrW == NULL) return FALSE; Temp = (LPBYTE) _cmsMalloc(nTabSize); @@ -662,6 +670,15 @@ // some profiles does claim to do that. Poor lcms will try // to detect such condition and fix up "on the fly". + switch (sig) { + + case icSigBToA0Tag: + case icSigBToA1Tag: + case icSigBToA2Tag: + case icSigGamutTag: + case icSigPreview0Tag: + case icSigPreview1Tag: + case icSigPreview2Tag: { LPWORD WhiteLab, ExpectedWhite; WORD WhiteFixed[MAXCHANNELS], WhiteUnfixed[MAXCHANNELS]; @@ -701,7 +718,10 @@ } } + break; + default:; + } } return TRUE; @@ -736,6 +756,9 @@ NewLUT -> InputEntries = LUT16.inputEnt; NewLUT -> OutputEntries = LUT16.outputEnt; + if (!_cmsValidateLUT(NewLUT)) { + return FALSE; + } // Matrix handling @@ -798,11 +821,9 @@ NewLUT->InputChan)); if (nTabSize > 0) { - PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * nTabSize); - if (PtrW == NULL) { - _cmsFree(PtrW); + PtrW = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize); + if (PtrW == NULL) return FALSE; - } NewLUT -> T = PtrW; NewLUT -> Tsize = (unsigned int) (nTabSize * sizeof(WORD)); @@ -1108,15 +1129,24 @@ static LCMSBOOL ReadCLUT(LPLCMSICCPROFILE Icc, size_t Offset, LPLUT NewLUT) { - + unsigned int j; icCLutStruct CLUT; if (Icc -> Seek(Icc, Offset)) return FALSE; if (Icc ->Read(&CLUT, sizeof(icCLutStruct), 1, Icc) != 1) return FALSE; - cmsAlloc3DGrid(NewLUT, CLUT.gridPoints[0], NewLUT ->InputChan, - NewLUT ->OutputChan); + for (j=1; j < NewLUT ->InputChan; j++) { + if (CLUT.gridPoints[0] != CLUT.gridPoints[j]) { + cmsSignalError(LCMS_ERRC_ABORTED, "CLUT with different granulatity is currently unsupported."); + return FALSE; + } + + + } + + if (cmsAlloc3DGrid(NewLUT, CLUT.gridPoints[0], NewLUT ->InputChan, + NewLUT ->OutputChan) == NULL) return FALSE; // Precission can be 1 or 2 bytes @@ -1173,10 +1203,11 @@ else nCurves = NewLUT ->OutputChan; + ZeroMemory(Curves, sizeof(Curves)); for (i=0; i < nCurves; i++) { Curves[i] = ReadCurve(Icc); - if (Curves[i] == NULL) return FALSE; + if (Curves[i] == NULL) goto Error; SkipAlignment(Icc); } @@ -1188,6 +1219,16 @@ return TRUE; +Error: + for (i=0; i < nCurves; i++) { + + if (Curves[i]) + cmsFreeGamma(Curves[i]); + } + + return FALSE; + + } // V4 stuff. LutAtoB type @@ -1209,6 +1250,13 @@ NewLUT -> InputChan = LUT16.inputChan; NewLUT -> OutputChan = LUT16.outputChan; + // Validate the NewLUT here to avoid excessive number of channels + // (leading to stack-based buffer overflow in ReadSetOfCurves). + // Needs revalidation after table size is filled in. + if (!_cmsValidateLUT(NewLUT)) { + return FALSE; + } + AdjustEndianess32((LPBYTE) &LUT16.offsetB); AdjustEndianess32((LPBYTE) &LUT16.offsetMat); AdjustEndianess32((LPBYTE) &LUT16.offsetM); @@ -1268,6 +1316,13 @@ NewLUT -> InputChan = LUT16.inputChan; NewLUT -> OutputChan = LUT16.outputChan; + // Validate the NewLUT here to avoid excessive number of channels + // (leading to stack-based buffer overflow in ReadSetOfCurves). + // Needs revalidation after table size is filled in. + if (!_cmsValidateLUT(NewLUT)) { + return FALSE; + } + AdjustEndianess32((LPBYTE) &LUT16.offsetB); AdjustEndianess32((LPBYTE) &LUT16.offsetMat); AdjustEndianess32((LPBYTE) &LUT16.offsetM); @@ -1558,6 +1613,8 @@ for (i=0; i < Offset; i++) { char Discard; + // No return checking; could lead to large loop in + // combination with int oflow above computing Offset. Icc ->Read(&Discard, 1, 1, Icc); } @@ -1566,7 +1623,7 @@ if (Len < 0) Len = 0; if (Len > 20*1024) Len = 20 * 1024; - wchar = (wchar_t*) _cmsMalloc(Len+2); + wchar = (wchar_t*) _cmsMalloc(Len*sizeof(wchar_t)+2); if (!wchar) return -1; if (Icc ->Read(wchar, 1, Len, Icc) != Len) return -1; @@ -1942,6 +1999,8 @@ char Root[33]; ZeroMemory(Colorant, sizeof(WORD) * MAXCHANNELS); + // No return value checking; could cause trouble with + // large count. Icc -> Read(Root, 1, 32, Icc); Icc -> Read(PCS, 3, sizeof(WORD), Icc); @@ -1975,7 +2034,8 @@ LPcmsNAMEDCOLORLIST LCMSEXPORT cmsReadColorantTable(cmsHPROFILE hProfile, icTagSignature sig) { - icInt32Number n, Count, i; + icInt32Number n; + icUInt32Number Count, i; size_t offset; icTagTypeSignature BaseType; LPLCMSICCPROFILE Icc = (LPLCMSICCPROFILE) (LPSTR) hProfile; @@ -2316,6 +2376,10 @@ Icc ->Read(&Count, sizeof(icUInt32Number), 1, Icc); AdjustEndianess32((LPBYTE) &Count); + if (Count > 1000) { + return NULL; + } + size = sizeof(int) + Count * sizeof(cmsPSEQDESC); OutSeq = (LPcmsSEQ) _cmsMalloc(size); if (OutSeq == NULL) return NULL; @@ -2496,7 +2560,7 @@ NewIcc = _cmsCreateProfileFromFilePlaceholder(lpFileName); if (!NewIcc) return NULL; - if (!ReadHeader(NewIcc, FALSE)) return NULL; + if (!ReadHeader(NewIcc, FALSE, 0)) return NULL; ReadCriticalTags(NewIcc); @@ -2516,7 +2580,7 @@ NewIcc = _cmsCreateProfileFromMemPlaceholder(MemPtr, dwSize); if (!NewIcc) return NULL; - if (!ReadHeader(NewIcc, TRUE)) return NULL; + if (!ReadHeader(NewIcc, TRUE, dwSize)) return NULL; ReadCriticalTags(NewIcc); --- lcms-1.17/src/cmslut.c +++ lcms-1.18/src/cmslut.c @@ -183,6 +183,37 @@ } +LCMSBOOL _cmsValidateLUT(LPLUT NewLUT) +{ + unsigned int calc = 1; + unsigned int oldCalc; + unsigned int power = NewLUT -> InputChan; + + if (NewLUT -> cLutPoints > 100) return FALSE; + if (NewLUT -> InputChan > MAXCHANNELS) return FALSE; + if (NewLUT -> OutputChan > MAXCHANNELS) return FALSE; + + if (NewLUT -> cLutPoints == 0) return TRUE; + + for (; power > 0; power--) { + + oldCalc = calc; + calc *= NewLUT -> cLutPoints; + + if (calc < oldCalc || calc < NewLUT -> cLutPoints) { + return FALSE; + } + } + + oldCalc = calc; + calc *= NewLUT -> OutputChan; + if (calc < oldCalc || calc < NewLUT -> OutputChan) { + return FALSE; + } + + return TRUE; +} + LPLUT LCMSEXPORT cmsAlloc3DGrid(LPLUT NewLUT, int clutPoints, int inputChan, int outputChan) { DWORD nTabSize; @@ -192,12 +223,15 @@ NewLUT -> InputChan = inputChan; NewLUT -> OutputChan = outputChan; + if (!_cmsValidateLUT(NewLUT)) { + return NULL; + } - nTabSize = (NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints, - NewLUT->InputChan) - * sizeof(WORD)); + nTabSize = NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints, + NewLUT->InputChan); - NewLUT -> T = (LPWORD) _cmsMalloc(nTabSize); + NewLUT -> T = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize); + nTabSize *= sizeof(WORD); if (NewLUT -> T == NULL) return NULL; ZeroMemory(NewLUT -> T, nTabSize);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor