diff options
author | Michael Nottebrock <lofi@FreeBSD.org> | 2007-03-30 18:15:08 +0000 |
---|---|---|
committer | Michael Nottebrock <lofi@FreeBSD.org> | 2007-03-30 18:15:08 +0000 |
commit | bf4e60e8bfb5be3d1939f2f2b41973b3faf5f67b (patch) | |
tree | b682bea2b50d3c979b9eb2c0bfdcb65256d774a0 | |
parent | - Update to 0.21 (diff) |
Fix handling of overlong UTF8 sequences in Qt and kdelibs, which, unpatched,
introduces XSS vulnerabilities in Konqueror and potentially affect any
Qt/KDE applications which deal with URLs or paths from untrusted locations.
Security: CVE-2007-0242
Notes
Notes:
svn path=/head/; revision=188834
-rw-r--r-- | devel/qt4-corelib/Makefile | 3 | ||||
-rw-r--r-- | devel/qt4-corelib/files/patch-utf8-bug-qt4 | 132 | ||||
-rw-r--r-- | x11-toolkits/qt33/Makefile | 1 | ||||
-rw-r--r-- | x11-toolkits/qt33/files/patch-utf8-bug-qt3 | 101 | ||||
-rw-r--r-- | x11/kdelibs3/Makefile | 2 | ||||
-rw-r--r-- | x11/kdelibs3/files/patch-kdelibs-kjs | 38 | ||||
-rw-r--r-- | x11/kdelibs4/Makefile | 2 | ||||
-rw-r--r-- | x11/kdelibs4/files/patch-kdelibs-kjs | 38 |
8 files changed, 314 insertions, 3 deletions
diff --git a/devel/qt4-corelib/Makefile b/devel/qt4-corelib/Makefile index 91592cfd02a9..02d4e000cb9b 100644 --- a/devel/qt4-corelib/Makefile +++ b/devel/qt4-corelib/Makefile @@ -8,7 +8,7 @@ PORTNAME= corelib PORTVERSION= 4.2.3 -PORTREVISION= 0 +PORTREVISION= 1 CATEGORIES?= devel MASTER_SITES= ${MASTER_SITE_QT} PKGNAMEPREFIX= qt4- @@ -62,6 +62,7 @@ EXTRACT_AFTER_ARGS=| ${TAR} -xf - \ --exclude '${DISTNAME}/tools/qtconfig' --exclude '${DISTNAME}/tools/qvfb' WRKSRC= ${WRKDIR}/${DISTNAME}/src/${PORTNAME} CONFIGURE_WRKSRC=${WRKSRC}/../../ +PATCH_WRKSRC=${WRKSRC}/../../ .include <bsd.port.pre.mk> diff --git a/devel/qt4-corelib/files/patch-utf8-bug-qt4 b/devel/qt4-corelib/files/patch-utf8-bug-qt4 new file mode 100644 index 000000000000..4b7ee9c81401 --- /dev/null +++ b/devel/qt4-corelib/files/patch-utf8-bug-qt4 @@ -0,0 +1,132 @@ +--- src/corelib/tools/qstring.cpp ++++ src/corelib/tools/qstring.cpp +@@ -3342,6 +3342,7 @@ QString QString::fromUtf8(const char *st + result.resize(size); // worst case + ushort *qch = result.d->data; + uint uc = 0; ++ uint min_uc = 0; + int need = 0; + int error = -1; + uchar ch; +@@ -3359,6 +3360,12 @@ QString QString::fromUtf8(const char *st + ushort low = uc%0x400 + 0xdc00; + *qch++ = high; + *qch++ = 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++ = 0xdbff; ++ *qch++ = 0xde00 + ((uchar)str[i]); + } else { + *qch++ = uc; + } +@@ -3381,14 +3388,17 @@ QString QString::fromUtf8(const char *st + 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); +--- src/corelib/codecs/qutfcodec.cpp ++++ src/corelib/codecs/qutfcodec.cpp +@@ -117,15 +117,19 @@ QString QUtf8Codec::convertToUnicode(con + bool headerdone = false; + QChar replacement = QChar::ReplacementCharacter; + int need = 0; ++ int error = -1; + uint uc = 0; ++ uint min_uc = 0; + if (state) { + if (state->flags & IgnoreHeader) + headerdone = true; + if (state->flags & ConvertInvalidToNull) + replacement = QChar::Null; + need = state->remainingChars; +- if (need) ++ if (need) { + uc = state->state_data[0]; ++ min_uc = state->state_data[1]; ++ } + } + if (!headerdone && len > 3 + && (uchar)chars[0] == 0xef && (uchar)chars[1] == 0xbb && (uchar)chars[2] == 0xbf) { +@@ -142,7 +146,7 @@ QString QUtf8Codec::convertToUnicode(con + int invalid = 0; + + for (int i=0; i<len; i++) { +- ch = *chars++; ++ ch = chars[i]; + if (need) { + if ((ch&0xc0) == 0x80) { + uc = (uc << 6) | (ch & 0x3f); +@@ -153,14 +157,27 @@ QString QUtf8Codec::convertToUnicode(con + uc -= 0x10000; + unsigned short high = uc/0x400 + 0xd800; + unsigned short low = uc%0x400 + 0xdc00; ++ ++ // resize if necessary ++ long where = qch - result.unicode(); ++ if (where + 2 >= result.size()) { ++ result.resize(where + 2); ++ qch = result.data() + where; ++ } ++ + *qch++ = QChar(high); + *qch++ = QChar(low); ++ } else if ((uc < min_uc) || (uc >= 0xd800 && uc <= 0xdfff) || (uc >= 0xfffe)) { ++ // error ++ *qch++ = QChar::ReplacementCharacter; ++ ++invalid; + } else { + *qch++ = uc; + } + } + } else { + // error ++ i = error; + *qch++ = QChar::ReplacementCharacter; + ++invalid; + need = 0; +@@ -171,12 +188,22 @@ QString QUtf8Codec::convertToUnicode(con + } 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::ReplacementCharacter; ++ ++invalid; + } + } + } +@@ -187,6 +214,7 @@ QString QUtf8Codec::convertToUnicode(con + if (headerdone) + state->flags |= IgnoreHeader; + state->state_data[0] = need ? uc : 0; ++ state->state_data[1] = need ? min_uc : 0; + } + return result; + } diff --git a/x11-toolkits/qt33/Makefile b/x11-toolkits/qt33/Makefile index 0066629e1cbf..c4bab954fb4d 100644 --- a/x11-toolkits/qt33/Makefile +++ b/x11-toolkits/qt33/Makefile @@ -8,6 +8,7 @@ PORTNAME= qt PORTVERSION= 3.3.8 +PORTREVISION= 1 CATEGORIES?= x11-toolkits ipv6 MASTER_SITES= ${MASTER_SITE_QT} DISTNAME= qt-x11-free-${PORTVERSION} diff --git a/x11-toolkits/qt33/files/patch-utf8-bug-qt3 b/x11-toolkits/qt33/files/patch-utf8-bug-qt3 new file mode 100644 index 000000000000..43e84a99f1e9 --- /dev/null +++ b/x11-toolkits/qt33/files/patch-utf8-bug-qt3 @@ -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); diff --git a/x11/kdelibs3/Makefile b/x11/kdelibs3/Makefile index 29e6ba4a6d11..ae053ee1e061 100644 --- a/x11/kdelibs3/Makefile +++ b/x11/kdelibs3/Makefile @@ -8,7 +8,7 @@ PORTNAME= kdelibs PORTVERSION= ${KDE_VERSION} -PORTREVISION= 1 +PORTREVISION= 2 CATEGORIES= x11 kde ipv6 MASTER_SITES= ${MASTER_SITE_KDE} MASTER_SITE_SUBDIR= stable/${PORTVERSION:S/.0//}/src diff --git a/x11/kdelibs3/files/patch-kdelibs-kjs b/x11/kdelibs3/files/patch-kdelibs-kjs new file mode 100644 index 000000000000..ca4456320ee9 --- /dev/null +++ b/x11/kdelibs3/files/patch-kdelibs-kjs @@ -0,0 +1,38 @@ +------------------------------------------------------------------------ +r645387 | porten | 2007-03-22 15:01:13 +0100 (Thu, 22 Mar 2007) | 4 lines + +substitute some of the invalid sequences with the standard replacement +char. this matches Mozilla but not IE which leaves them unchanged (or +throws an exception) + +------------------------------------------------------------------------ +--- kjs/function.cpp ++++ kjs/function.cpp +@@ -244,11 +244,15 @@ UString decodeURI(ExecState *exec, UStri + } + + // UTF-8 transform ++ const unsigned long replacementChar = 0xFFFD; + unsigned long V; + if (n == 2) { + unsigned long yyyyy = octets[0] & 0x1F; + unsigned long zzzzzz = octets[1] & 0x3F; + V = (yyyyy << 6) | zzzzzz; ++ // 2-byte sequence overlong for this value? ++ if (V < 0xFF) ++ V = replacementChar; + C = UChar((unsigned short)V); + } + else if (n == 3) { +@@ -256,6 +260,11 @@ UString decodeURI(ExecState *exec, UStri + unsigned long yyyyyy = octets[1] & 0x3F; + unsigned long zzzzzz = octets[2] & 0x3F; + V = (xxxx << 12) | (yyyyyy << 6) | zzzzzz; ++ // 3-byte sequence overlong for this value, ++ // an invalid value or UTF-16 surrogate? ++ if (V < 0x800 || V == 0xFFFE || V == 0xFFFF || ++ (V >= 0xD800 && V <= 0xDFFF)) ++ V = replacementChar; + C = UChar((unsigned short)V); + } + else { diff --git a/x11/kdelibs4/Makefile b/x11/kdelibs4/Makefile index 29e6ba4a6d11..ae053ee1e061 100644 --- a/x11/kdelibs4/Makefile +++ b/x11/kdelibs4/Makefile @@ -8,7 +8,7 @@ PORTNAME= kdelibs PORTVERSION= ${KDE_VERSION} -PORTREVISION= 1 +PORTREVISION= 2 CATEGORIES= x11 kde ipv6 MASTER_SITES= ${MASTER_SITE_KDE} MASTER_SITE_SUBDIR= stable/${PORTVERSION:S/.0//}/src diff --git a/x11/kdelibs4/files/patch-kdelibs-kjs b/x11/kdelibs4/files/patch-kdelibs-kjs new file mode 100644 index 000000000000..ca4456320ee9 --- /dev/null +++ b/x11/kdelibs4/files/patch-kdelibs-kjs @@ -0,0 +1,38 @@ +------------------------------------------------------------------------ +r645387 | porten | 2007-03-22 15:01:13 +0100 (Thu, 22 Mar 2007) | 4 lines + +substitute some of the invalid sequences with the standard replacement +char. this matches Mozilla but not IE which leaves them unchanged (or +throws an exception) + +------------------------------------------------------------------------ +--- kjs/function.cpp ++++ kjs/function.cpp +@@ -244,11 +244,15 @@ UString decodeURI(ExecState *exec, UStri + } + + // UTF-8 transform ++ const unsigned long replacementChar = 0xFFFD; + unsigned long V; + if (n == 2) { + unsigned long yyyyy = octets[0] & 0x1F; + unsigned long zzzzzz = octets[1] & 0x3F; + V = (yyyyy << 6) | zzzzzz; ++ // 2-byte sequence overlong for this value? ++ if (V < 0xFF) ++ V = replacementChar; + C = UChar((unsigned short)V); + } + else if (n == 3) { +@@ -256,6 +260,11 @@ UString decodeURI(ExecState *exec, UStri + unsigned long yyyyyy = octets[1] & 0x3F; + unsigned long zzzzzz = octets[2] & 0x3F; + V = (xxxx << 12) | (yyyyyy << 6) | zzzzzz; ++ // 3-byte sequence overlong for this value, ++ // an invalid value or UTF-16 surrogate? ++ if (V < 0x800 || V == 0xFFFE || V == 0xFFFF || ++ (V >= 0xD800 && V <= 0xDFFF)) ++ V = replacementChar; + C = UChar((unsigned short)V); + } + else { |