1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-11-26 00:55:14 +00:00

Fix possible crash/DOS bug in JPEG kfile-info plugin.

Security: http://www.kde.org/info/security/advisory-20061129-1.txt
This commit is contained in:
Michael Nottebrock 2006-12-01 18:34:33 +00:00
parent 255ecbe884
commit b22bea7a69
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=178497
4 changed files with 270 additions and 0 deletions

View File

@ -8,6 +8,7 @@
PORTNAME= kdegraphics
PORTVERSION= ${KDE_VERSION}
PORTREVISION= 1
CATEGORIES= graphics kde
MASTER_SITES= ${MASTER_SITE_KDE}
MASTER_SITE_SUBDIR= stable/${PORTVERSION:S/.0//}/src

View File

@ -0,0 +1,134 @@
--- kfile-plugins/jpeg/exif.h
+++ kfile-plugins/jpeg/exif.h
@@ -72,7 +72,8 @@
int Get32s(void * Long);
unsigned Get32u(void * Long);
double ConvertAnyFormat(void * ValuePtr, int Format);
- void ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength);
+ void ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength,
+ unsigned NestingLevel);
void process_COM (const uchar * Data, int length);
void process_SOFn (const uchar * Data, int marker);
int Get16m(const void * Short);
--- kfile-plugins/jpeg/exif.cpp
+++ kfile-plugins/jpeg/exif.cpp
@@ -446,7 +446,7 @@
//--------------------------------------------------------------------------
// Process one of the nested EXIF directories.
//--------------------------------------------------------------------------
-void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength)
+void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength, unsigned NestingLevel)
{
int de;
int a;
@@ -454,6 +454,9 @@
unsigned ThumbnailOffset = 0;
unsigned ThumbnailSize = 0;
+ if ( NestingLevel > 4)
+ throw FatalError("Maximum directory nesting exceeded (corrupt exif header)");
+
NumDirEntries = Get16u(DirStart);
#define DIR_ENTRY_ADDR(Start, Entry) (Start+2+12*(Entry))
@@ -476,7 +479,7 @@
for (de=0;de<NumDirEntries;de++){
int Tag, Format, Components;
unsigned char * ValuePtr;
- int ByteCount;
+ unsigned ByteCount;
char * DirEntry;
DirEntry = (char *)DIR_ENTRY_ADDR(DirStart, de);
@@ -489,6 +492,11 @@
throw FatalError("Illegal format code in EXIF dir");
}
+ if ((unsigned)Components > 0x10000) {
+ throw FatalError("Illegal number of components for tag");
+ continue;
+ }
+
ByteCount = Components * BytesPerFormat[Format];
if (ByteCount > 4){
@@ -517,11 +525,11 @@
switch(Tag){
case TAG_MAKE:
- ExifData::CameraMake = QString((char*)ValuePtr);
+ ExifData::CameraMake = QString::fromLatin1((const char*)ValuePtr, 31);
break;
case TAG_MODEL:
- ExifData::CameraModel = QString((char*)ValuePtr);
+ ExifData::CameraModel = QString::fromLatin1((const char*)ValuePtr, 39);
break;
case TAG_ORIENTATION:
@@ -529,7 +537,7 @@
break;
case TAG_DATETIME_ORIGINAL:
- DateTime = QString((char*)ValuePtr);
+ DateTime = QString::fromLatin1((const char*)ValuePtr, 19);
break;
case TAG_USERCOMMENT:
@@ -550,14 +558,12 @@
int c;
c = (ValuePtr)[a];
if (c != '\0' && c != ' '){
- //strncpy(ImageInfo.Comments, (const char*)(a+ValuePtr), 199);
- UserComment.sprintf("%s", (const char*)(a+ValuePtr));
+ UserComment = QString::fromLatin1((const char*)(a+ValuePtr), 199);
break;
}
}
}else{
- //strncpy(ImageInfo.Comments, (const char*)ValuePtr, 199);
- UserComment.sprintf("%s", (const char*)ValuePtr);
+ UserComment = QString::fromLatin1((const char*)ValuePtr, 199);
}
break;
@@ -676,10 +682,10 @@
if (Tag == TAG_EXIF_OFFSET || Tag == TAG_INTEROP_OFFSET){
unsigned char * SubdirStart;
SubdirStart = OffsetBase + Get32u(ValuePtr);
- if (SubdirStart < OffsetBase || SubdirStart > OffsetBase+ExifLength){
+ if (SubdirStart <= OffsetBase || SubdirStart >= OffsetBase+ExifLength){
throw FatalError("Illegal subdirectory link");
}
- ProcessExifDir(SubdirStart, OffsetBase, ExifLength);
+ ProcessExifDir(SubdirStart, OffsetBase, ExifLength, NestingLevel+1);
continue;
}
}
@@ -709,7 +715,7 @@
}
}else{
if (SubdirStart <= OffsetBase+ExifLength){
- ProcessExifDir(SubdirStart, OffsetBase, ExifLength);
+ ProcessExifDir(SubdirStart, OffsetBase, ExifLength, NestingLevel+1);
}
}
}
@@ -719,7 +725,7 @@
}
if (ThumbnailSize && ThumbnailOffset){
- if (ThumbnailSize + ThumbnailOffset <= ExifLength){
+ if (ThumbnailSize + ThumbnailOffset < ExifLength){
// The thumbnail pointer appears to be valid. Store it.
Thumbnail.loadFromData(OffsetBase + ThumbnailOffset, ThumbnailSize, "JPEG");
}
@@ -810,7 +816,7 @@
LastExifRefd = CharBuf;
// First directory starts 16 bytes in. Offsets start at 8 bytes in.
- ProcessExifDir(CharBuf+16, CharBuf+8, length-6);
+ ProcessExifDir(CharBuf+16, CharBuf+8, length-6, 0);
// This is how far the interesting (non thumbnail) part of the exif went.
ExifSettingsLength = LastExifRefd - CharBuf;

View File

@ -8,6 +8,7 @@
PORTNAME= kdegraphics
PORTVERSION= ${KDE_VERSION}
PORTREVISION= 1
CATEGORIES= graphics kde
MASTER_SITES= ${MASTER_SITE_KDE}
MASTER_SITE_SUBDIR= stable/${PORTVERSION:S/.0//}/src

View File

@ -0,0 +1,134 @@
--- kfile-plugins/jpeg/exif.h
+++ kfile-plugins/jpeg/exif.h
@@ -72,7 +72,8 @@
int Get32s(void * Long);
unsigned Get32u(void * Long);
double ConvertAnyFormat(void * ValuePtr, int Format);
- void ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength);
+ void ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength,
+ unsigned NestingLevel);
void process_COM (const uchar * Data, int length);
void process_SOFn (const uchar * Data, int marker);
int Get16m(const void * Short);
--- kfile-plugins/jpeg/exif.cpp
+++ kfile-plugins/jpeg/exif.cpp
@@ -446,7 +446,7 @@
//--------------------------------------------------------------------------
// Process one of the nested EXIF directories.
//--------------------------------------------------------------------------
-void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength)
+void ExifData::ProcessExifDir(unsigned char * DirStart, unsigned char * OffsetBase, unsigned ExifLength, unsigned NestingLevel)
{
int de;
int a;
@@ -454,6 +454,9 @@
unsigned ThumbnailOffset = 0;
unsigned ThumbnailSize = 0;
+ if ( NestingLevel > 4)
+ throw FatalError("Maximum directory nesting exceeded (corrupt exif header)");
+
NumDirEntries = Get16u(DirStart);
#define DIR_ENTRY_ADDR(Start, Entry) (Start+2+12*(Entry))
@@ -476,7 +479,7 @@
for (de=0;de<NumDirEntries;de++){
int Tag, Format, Components;
unsigned char * ValuePtr;
- int ByteCount;
+ unsigned ByteCount;
char * DirEntry;
DirEntry = (char *)DIR_ENTRY_ADDR(DirStart, de);
@@ -489,6 +492,11 @@
throw FatalError("Illegal format code in EXIF dir");
}
+ if ((unsigned)Components > 0x10000) {
+ throw FatalError("Illegal number of components for tag");
+ continue;
+ }
+
ByteCount = Components * BytesPerFormat[Format];
if (ByteCount > 4){
@@ -517,11 +525,11 @@
switch(Tag){
case TAG_MAKE:
- ExifData::CameraMake = QString((char*)ValuePtr);
+ ExifData::CameraMake = QString::fromLatin1((const char*)ValuePtr, 31);
break;
case TAG_MODEL:
- ExifData::CameraModel = QString((char*)ValuePtr);
+ ExifData::CameraModel = QString::fromLatin1((const char*)ValuePtr, 39);
break;
case TAG_ORIENTATION:
@@ -529,7 +537,7 @@
break;
case TAG_DATETIME_ORIGINAL:
- DateTime = QString((char*)ValuePtr);
+ DateTime = QString::fromLatin1((const char*)ValuePtr, 19);
break;
case TAG_USERCOMMENT:
@@ -550,14 +558,12 @@
int c;
c = (ValuePtr)[a];
if (c != '\0' && c != ' '){
- //strncpy(ImageInfo.Comments, (const char*)(a+ValuePtr), 199);
- UserComment.sprintf("%s", (const char*)(a+ValuePtr));
+ UserComment = QString::fromLatin1((const char*)(a+ValuePtr), 199);
break;
}
}
}else{
- //strncpy(ImageInfo.Comments, (const char*)ValuePtr, 199);
- UserComment.sprintf("%s", (const char*)ValuePtr);
+ UserComment = QString::fromLatin1((const char*)ValuePtr, 199);
}
break;
@@ -676,10 +682,10 @@
if (Tag == TAG_EXIF_OFFSET || Tag == TAG_INTEROP_OFFSET){
unsigned char * SubdirStart;
SubdirStart = OffsetBase + Get32u(ValuePtr);
- if (SubdirStart < OffsetBase || SubdirStart > OffsetBase+ExifLength){
+ if (SubdirStart <= OffsetBase || SubdirStart >= OffsetBase+ExifLength){
throw FatalError("Illegal subdirectory link");
}
- ProcessExifDir(SubdirStart, OffsetBase, ExifLength);
+ ProcessExifDir(SubdirStart, OffsetBase, ExifLength, NestingLevel+1);
continue;
}
}
@@ -709,7 +715,7 @@
}
}else{
if (SubdirStart <= OffsetBase+ExifLength){
- ProcessExifDir(SubdirStart, OffsetBase, ExifLength);
+ ProcessExifDir(SubdirStart, OffsetBase, ExifLength, NestingLevel+1);
}
}
}
@@ -719,7 +725,7 @@
}
if (ThumbnailSize && ThumbnailOffset){
- if (ThumbnailSize + ThumbnailOffset <= ExifLength){
+ if (ThumbnailSize + ThumbnailOffset < ExifLength){
// The thumbnail pointer appears to be valid. Store it.
Thumbnail.loadFromData(OffsetBase + ThumbnailOffset, ThumbnailSize, "JPEG");
}
@@ -810,7 +816,7 @@
LastExifRefd = CharBuf;
// First directory starts 16 bytes in. Offsets start at 8 bytes in.
- ProcessExifDir(CharBuf+16, CharBuf+8, length-6);
+ ProcessExifDir(CharBuf+16, CharBuf+8, length-6, 0);
// This is how far the interesting (non thumbnail) part of the exif went.
ExifSettingsLength = LastExifRefd - CharBuf;