CVE-2007-0242 QT UTF8 improper character expansion

This commit is contained in:
Than Ngo 2007-08-29 17:30:40 +00:00
parent a7c2b54a92
commit adf970ce5b
2 changed files with 107 additions and 1 deletions

View File

@ -1,7 +1,7 @@
Summary: The shared library for the Qt GUI toolkit.
Name: qt
Version: 3.3.8
Release: 6%{?dist}
Release: 6%{?dist}.1
Epoch: 1
License: GPL/QPL
Group: System Environment/Libraries
@ -65,6 +65,7 @@ Patch201: qt-x11-free-3.3.8-bz#243722-mysql.patch
# security patces
Patch300: qt3-CVE-2007-3388.patch
Patch301: utf8-bug-qt3-CVE-2007-0242.diff
%define qt_dirname qt-3.3
%define qtdir %{_libdir}/%{qt_dirname}
@ -305,6 +306,7 @@ for the Qt toolkit.
# security patches
%patch300 -p1 -b .CVE-2007-3388
%patch301 -p0 -b .CVE-2007-0242
# convert to UTF-8
iconv -f iso-8859-1 -t utf-8 < doc/man/man3/qdial.3qt > doc/man/man3/qdial.3qt_
@ -576,6 +578,9 @@ rm -rf %{buildroot}
%changelog
* Wed Aug 29 2007 Than Ngo <than@redhat.com> - 1:3.3.8-6.fc7.1
- CVE-2007-0242, UTF8 improper character expansion
* Tue Aug 28 2007 Than Ngo <than@redhat.com> - 1:3.3.8-6.fc7
- CVE-2007-3388 qt3 format string flaw

View File

@ -0,0 +1,101 @@
--- src/codecs/qutfcodec.cpp
+++ src/codecs/qutfcodec.cpp
@@ -154,6 +154,7 @@
class QUtf8Decoder : public QTextDecoder {
uint uc;
+ uint min_uc;
int need;
bool headerDone;
public:
@@ -167,8 +168,9 @@
result.setLength( len ); // worst case
QChar *qch = (QChar *)result.unicode();
uchar ch;
+ int error = -1;
for (int i=0; i<len; i++) {
- ch = *chars++;
+ ch = chars[i];
if (need) {
if ( (ch&0xc0) == 0x80 ) {
uc = (uc << 6) | (ch & 0x3f);
@@ -182,6 +184,8 @@
*qch++ = QChar(high);
*qch++ = QChar(low);
headerDone = TRUE;
+ } else if ((uc < min_uc) || (uc >= 0xd800 && uc <= 0xdfff) || (uc >= 0xfffe)) {
+ *qch++ = QChar::replacement;
} else {
if (headerDone || QChar(uc) != QChar::byteOrderMark)
*qch++ = uc;
@@ -190,6 +194,7 @@
}
} else {
// error
+ i = error;
*qch++ = QChar::replacement;
need = 0;
}
@@ -200,12 +205,21 @@
} else if ((ch & 0xe0) == 0xc0) {
uc = ch & 0x1f;
need = 1;
+ error = i;
+ min_uc = 0x80;
} else if ((ch & 0xf0) == 0xe0) {
uc = ch & 0x0f;
need = 2;
+ error = i;
+ min_uc = 0x800;
} else if ((ch&0xf8) == 0xf0) {
uc = ch & 0x07;
need = 3;
+ error = i;
+ min_uc = 0x10000;
+ } else {
+ // error
+ *qch++ = QChar::replacement;
}
}
}
--- src/tools/qstring.cpp
+++ src/tools/qstring.cpp
@@ -5805,6 +5805,7 @@
result.setLength( len ); // worst case
QChar *qch = (QChar *)result.unicode();
uint uc = 0;
+ uint min_uc = 0;
int need = 0;
int error = -1;
uchar ch;
@@ -5822,6 +5823,12 @@
unsigned short low = uc%0x400 + 0xdc00;
*qch++ = QChar(high);
*qch++ = QChar(low);
+ } else if (uc < min_uc || (uc >= 0xd800 && uc <= 0xdfff) || (uc >= 0xfffe)) {
+ // overlong seqence, UTF16 surrogate or BOM
+ i = error;
+ qch = addOne(qch, result);
+ *qch++ = QChar(0xdbff);
+ *qch++ = QChar(0xde00+((uchar)utf8[i]));
} else {
*qch++ = uc;
}
@@ -5844,14 +5851,17 @@
uc = ch & 0x1f;
need = 1;
error = i;
+ min_uc = 0x80;
} else if ((ch & 0xf0) == 0xe0) {
uc = ch & 0x0f;
need = 2;
error = i;
+ min_uc = 0x800;
} else if ((ch&0xf8) == 0xf0) {
uc = ch & 0x07;
need = 3;
error = i;
+ min_uc = 0x10000;
} else {
// Error
qch = addOne(qch, result);