Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 183153 Details for
Bug 260269
<media-libs/lcms-1.18 integer overflows (CVE-2009-{0581,0723,0733})
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
lcms-1.17-CVE-2009-0581.patch
lcms-1.17-CVE-2009-0581.patch (text/plain), 12.83 KB, created by
Robert Buchholz (RETIRED)
on 2009-02-25 16:40:28 UTC
(
hide
)
Description:
lcms-1.17-CVE-2009-0581.patch
Filename:
MIME Type:
Creator:
Robert Buchholz (RETIRED)
Created:
2009-02-25 16:40:28 UTC
Size:
12.83 KB
patch
obsolete
>diff -uprN lcms-1.17/include/lcms.h lcms-1.17fixed/include/lcms.h >--- lcms-1.17/include/lcms.h 2007-07-27 12:00:01.000000000 +0200 >+++ lcms-1.17fixed/include/lcms.h 2009-02-24 01:07:47.000000000 +0100 >@@ -1412,6 +1412,14 @@ LCMS_INLINE void* _cmsMalloc(size_t size > 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) > { >diff -uprN lcms-1.17/src/cmsgamma.c lcms-1.17fixed/src/cmsgamma.c >--- lcms-1.17/src/cmsgamma.c 2007-07-27 12:00:02.000000000 +0200 >+++ lcms-1.17fixed/src/cmsgamma.c 2009-02-24 01:07:47.000000000 +0100 >@@ -114,7 +114,7 @@ LPGAMMATABLE LCMSEXPORT cmsAllocGamma(in > 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; > } >diff -uprN lcms-1.17/src/cmsio0.c lcms-1.17fixed/src/cmsio0.c >--- lcms-1.17/src/cmsio0.c 2007-07-27 12:00:02.000000000 +0200 >+++ lcms-1.17fixed/src/cmsio0.c 2009-02-24 01:07:47.000000000 +0100 >@@ -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 @@ size_t MemoryRead(LPVOID buffer, size_t > 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){ > >@@ -104,7 +114,7 @@ LCMSBOOL MemorySeek(struct _lcms_iccprof > return TRUE; > } > >- ResData ->Pointer = (DWORD) offset; >+ ResData ->Pointer = offset; > return FALSE; > } > >diff -uprN lcms-1.17/src/cmsio1.c lcms-1.17fixed/src/cmsio1.c >--- lcms-1.17/src/cmsio1.c 2007-07-27 12:00:02.000000000 +0200 >+++ lcms-1.17fixed/src/cmsio1.c 2009-02-24 01:10:21.000000000 +0100 >@@ -260,11 +260,14 @@ void EvalCHRM(LPcmsCIEXYZ Dest, LPMAT3 C > // 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; >@@ -286,6 +289,10 @@ LPLCMSICCPROFILE ReadHeader(LPLCMSICCPRO > > if (Header.magic != icMagicNumber) goto ErrorCleanup; > >+ if (dwSize && dwSize != Header.size) { >+ goto ErrorCleanup; >+ } >+ > if (Icc ->Read(&TagCount, sizeof(icInt32Number), 1, Icc) != 1) > goto ErrorCleanup; > >@@ -320,7 +327,7 @@ LPLCMSICCPROFILE ReadHeader(LPLCMSICCPRO > > // 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; >@@ -337,8 +344,9 @@ LPLCMSICCPROFILE ReadHeader(LPLCMSICCPRO > 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; >@@ -363,7 +371,32 @@ ErrorCleanup: > } > > >+int >+validateNewLUT(LPLUT NewLUT) { >+ unsigned int calc = 1; >+ unsigned int oldCalc; >+ unsigned int power = NewLUT -> InputChan; >+ >+ if (NewLUT -> cLutPoints > 100) NewLUT ->cLutPoints = 100; >+ if (NewLUT -> InputChan > MAXCHANNELS) NewLUT -> InputChan = MAXCHANNELS; >+ if (NewLUT -> OutputChan > MAXCHANNELS) NewLUT -> OutputChan = MAXCHANNELS; >+ >+ for (; power > 0; power--) { >+ oldCalc = calc; >+ calc *= NewLUT -> cLutPoints; >+ if (calc < oldCalc || calc < NewLUT -> cLutPoints) { >+ return 0; >+ } >+ } >+ >+ oldCalc = calc; >+ calc *= NewLUT -> OutputChan; >+ if (calc < oldCalc || calc < NewLUT -> OutputChan) { >+ return 0; >+ } > >+ return 1; >+} > > static > unsigned int uipow(unsigned int a, unsigned int b) { >@@ -493,9 +526,9 @@ LCMSBOOL ReadLUT8(LPLCMSICCPROFILE Icc, > 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 (!validateNewLUT(NewLUT)) { >+ return FALSE; >+ } > > AdjustEndianess32((LPBYTE) &LUT8.e00); > AdjustEndianess32((LPBYTE) &LUT8.e01); >@@ -570,7 +603,7 @@ LCMSBOOL ReadLUT8(LPLCMSICCPROFILE Icc, > > if (nTabSize > 0) { > >- PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * nTabSize); >+ PtrW = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize); > if (PtrW == NULL) return FALSE; > > Temp = (LPBYTE) _cmsMalloc(nTabSize); >@@ -735,6 +768,9 @@ LCMSBOOL ReadLUT16(LPLCMSICCPROFILE Icc, > NewLUT -> InputEntries = LUT16.inputEnt; > NewLUT -> OutputEntries = LUT16.outputEnt; > >+ if (!validateNewLUT(NewLUT)) { >+ return FALSE; >+ } > > // Matrix handling > >@@ -797,7 +833,7 @@ LCMSBOOL ReadLUT16(LPLCMSICCPROFILE Icc, > NewLUT->InputChan)); > if (nTabSize > 0) { > >- PtrW = (LPWORD) _cmsMalloc(sizeof(WORD) * nTabSize); >+ PtrW = (LPWORD) _cmsCalloc(sizeof(WORD), nTabSize); > if (PtrW == NULL) { > _cmsFree(PtrW); > return FALSE; >@@ -1114,8 +1150,11 @@ LCMSBOOL ReadCLUT(LPLCMSICCPROFILE Icc, > if (Icc ->Read(&CLUT, sizeof(icCLutStruct), 1, Icc) != 1) return FALSE; > > >- cmsAlloc3DGrid(NewLUT, CLUT.gridPoints[0], NewLUT ->InputChan, >- NewLUT ->OutputChan); >+ if (cmsAlloc3DGrid(NewLUT, CLUT.gridPoints[0], >+ NewLUT ->InputChan, >+ NewLUT ->OutputChan) == NULL) { >+ return FALSE; >+ } > > // Precission can be 1 or 2 bytes > >@@ -1163,8 +1202,11 @@ LCMSBOOL ReadSetOfCurves(LPLCMSICCPROFIL > { > LPGAMMATABLE Curves[MAXCHANNELS]; > unsigned int i, nCurves; >+ LCMSBOOL ret = FALSE; > > if (Icc -> Seek(Icc, Offset)) return FALSE; >+ >+ ZeroMemory(Curves, sizeof(Curves)); > > if (nLocation == 1 || nLocation == 3) > >@@ -1175,17 +1217,20 @@ LCMSBOOL ReadSetOfCurves(LPLCMSICCPROFIL > for (i=0; i < nCurves; i++) { > > Curves[i] = ReadCurve(Icc); >- if (Curves[i] == NULL) return FALSE; >+ if (Curves[i] == NULL) goto free_out; > SkipAlignment(Icc); > > } > > NewLUT = cmsAllocLinearTable(NewLUT, Curves, nLocation); >- >+ >+ ret = TRUE; >+ >+free_out: > for (i=0; i < nCurves; i++) > cmsFreeGamma(Curves[i]); > >- return TRUE; >+ return ret; > > } > >@@ -1208,6 +1253,13 @@ LCMSBOOL ReadLUT_A2B(LPLCMSICCPROFILE Ic > 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 (!validateNewLUT(NewLUT)) { >+ return FALSE; >+ } >+ > AdjustEndianess32((LPBYTE) &LUT16.offsetB); > AdjustEndianess32((LPBYTE) &LUT16.offsetMat); > AdjustEndianess32((LPBYTE) &LUT16.offsetM); >@@ -1267,6 +1319,13 @@ LCMSBOOL ReadLUT_B2A(LPLCMSICCPROFILE Ic > 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 (!validateNewLUT(NewLUT)) { >+ return FALSE; >+ } >+ > AdjustEndianess32((LPBYTE) &LUT16.offsetB); > AdjustEndianess32((LPBYTE) &LUT16.offsetMat); > AdjustEndianess32((LPBYTE) &LUT16.offsetM); >@@ -1415,6 +1474,7 @@ int ReadEmbeddedTextTag(LPLCMSICCPROFILE > > > BaseType = ReadBase(Icc); >+ // Looks broken: size could be 0, or essentially < sizeof(icTagBase) here. > size -= sizeof(icTagBase); > > switch (BaseType) { >@@ -1557,6 +1617,8 @@ int ReadEmbeddedTextTag(LPLCMSICCPROFILE > 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); > } > >@@ -1572,6 +1634,7 @@ int ReadEmbeddedTextTag(LPLCMSICCPROFILE > AdjustEndianessArray16((LPWORD) wchar, Len / 2); > > wchar[Len / 2] = L'\0'; >+ // Failure to null terminate "Name". > i = wcstombs(Name, wchar, size_max ); > if (i == ((size_t) -1)) { > >@@ -1941,6 +2004,8 @@ int cmsReadICCnamedColorList(cmsHTRANSFO > 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); > >@@ -1974,7 +2039,8 @@ int cmsReadICCnamedColorList(cmsHTRANSFO > > 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; >@@ -2315,6 +2381,9 @@ LPcmsSEQ LCMSEXPORT cmsReadProfileSequen > 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; >@@ -2495,7 +2564,7 @@ cmsHPROFILE LCMSEXPORT cmsOpenProfileFro > NewIcc = _cmsCreateProfileFromFilePlaceholder(lpFileName); > if (!NewIcc) return NULL; > >- if (!ReadHeader(NewIcc, FALSE)) return NULL; >+ if (!ReadHeader(NewIcc, FALSE, 0)) return NULL; > > ReadCriticalTags(NewIcc); > >@@ -2515,7 +2584,7 @@ cmsHPROFILE LCMSEXPORT cmsOpenProfileFro > NewIcc = _cmsCreateProfileFromMemPlaceholder(MemPtr, dwSize); > if (!NewIcc) return NULL; > >- if (!ReadHeader(NewIcc, TRUE)) return NULL; >+ if (!ReadHeader(NewIcc, TRUE, dwSize)) return NULL; > > ReadCriticalTags(NewIcc); > >diff -uprN lcms-1.17/src/cmslut.c lcms-1.17fixed/src/cmslut.c >--- lcms-1.17/src/cmslut.c 2007-07-27 12:00:02.000000000 +0200 >+++ lcms-1.17fixed/src/cmslut.c 2009-02-24 01:07:47.000000000 +0100 >@@ -192,12 +192,14 @@ LPLUT LCMSEXPORT cmsAlloc3DGrid(LPLUT Ne > NewLUT -> InputChan = inputChan; > NewLUT -> OutputChan = outputChan; > >+ if (!validateNewLUT(NewLUT)) { >+ return NULL; >+ } >+ nTabSize = NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints, >+ NewLUT->InputChan); > >- nTabSize = (NewLUT -> OutputChan * UIpow(NewLUT->cLutPoints, >- NewLUT->InputChan) >- * sizeof(WORD)); >- >- 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);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 260269
:
183152
| 183153 |
183389
|
184243