1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
| | Copied from Debian.
Description: missing boundary checks in layout engine
It was discovered that ICU Layout Engine was missing multiple boundary checks.
These could lead to buffer overflows and memory corruption. A specially
crafted file could cause an application using ICU to parse untrusted font
files to crash and, possibly, execute arbitrary code.
Author: Laszlo Boszormenyi (GCS) <gcs@debian.org>
Origin: upstream, http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/3f9845510b47
Reviewed-By: srl, bae, mschoene
Forwarded: not-needed
Last-Update: 2015-07-30
---
--- icu-52.1.orig/source/layout/ContextualGlyphInsertionProc2.cpp
+++ icu-52.1/source/layout/ContextualGlyphInsertionProc2.cpp
@@ -82,6 +82,10 @@ le_uint16 ContextualGlyphInsertionProces
le_int16 markIndex = SWAPW(entry->markedInsertionListIndex);
if (markIndex > 0) {
+ if (markGlyph < 0 || markGlyph >= glyphStorage.getGlyphCount()) {
+ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+ return 0;
+ }
le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5;
le_bool isKashidaLike = (flags & cgiMarkedIsKashidaLike);
le_bool isBefore = (flags & cgiMarkInsertBefore);
@@ -90,6 +94,10 @@ le_uint16 ContextualGlyphInsertionProces
le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
if (currIndex > 0) {
+ if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
+ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+ return 0;
+ }
le_int16 count = flags & cgiCurrentInsertCountMask;
le_bool isKashidaLike = (flags & cgiCurrentIsKashidaLike);
le_bool isBefore = (flags & cgiCurrentInsertBefore);
--- icu-52.1.orig/source/layout/ContextualGlyphSubstProc.cpp
+++ icu-52.1/source/layout/ContextualGlyphSubstProc.cpp
@@ -51,6 +51,10 @@ ByteOffset ContextualGlyphSubstitutionPr
WordOffset currOffset = SWAPW(entry->currOffset);
if (markOffset != 0 && LE_SUCCESS(success)) {
+ if (markGlyph < 0 || markGlyph >= glyphStorage.getGlyphCount()) {
+ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+ return 0;
+ }
LEGlyphID mGlyph = glyphStorage[markGlyph];
TTGlyphID newGlyph = SWAPW(int16Table.getObject(markOffset + LE_GET_GLYPH(mGlyph), success)); // whew.
@@ -58,6 +62,10 @@ ByteOffset ContextualGlyphSubstitutionPr
}
if (currOffset != 0) {
+ if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
+ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+ return 0;
+ }
LEGlyphID thisGlyph = glyphStorage[currGlyph];
TTGlyphID newGlyph = SWAPW(int16Table.getObject(currOffset + LE_GET_GLYPH(thisGlyph), success)); // whew.
--- icu-52.1.orig/source/layout/ContextualGlyphSubstProc2.cpp
+++ icu-52.1/source/layout/ContextualGlyphSubstProc2.cpp
@@ -45,17 +45,25 @@ le_uint16 ContextualGlyphSubstitutionPro
if(LE_FAILURE(success)) return 0;
le_uint16 newState = SWAPW(entry->newStateIndex);
le_uint16 flags = SWAPW(entry->flags);
- le_int16 markIndex = SWAPW(entry->markIndex);
- le_int16 currIndex = SWAPW(entry->currIndex);
+ le_uint16 markIndex = SWAPW(entry->markIndex);
+ le_uint16 currIndex = SWAPW(entry->currIndex);
- if (markIndex != -1) {
+ if (markIndex != 0x0FFFF) {
+ if (markGlyph < 0 || markGlyph >= glyphStorage.getGlyphCount()) {
+ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+ return 0;
+ }
le_uint32 offset = SWAPL(perGlyphTable(markIndex, success));
LEGlyphID mGlyph = glyphStorage[markGlyph];
TTGlyphID newGlyph = lookup(offset, mGlyph, success);
glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
}
- if (currIndex != -1) {
+ if (currIndex != 0x0FFFF) {
+ if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
+ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+ return 0;
+ }
le_uint32 offset = SWAPL(perGlyphTable(currIndex, success));
LEGlyphID thisGlyph = glyphStorage[currGlyph];
TTGlyphID newGlyph = lookup(offset, thisGlyph, success);
--- icu-52.1.orig/source/layout/IndicRearrangementProcessor.cpp
+++ icu-52.1/source/layout/IndicRearrangementProcessor.cpp
@@ -45,6 +45,11 @@ ByteOffset IndicRearrangementProcessor::
ByteOffset newState = SWAPW(entry->newStateOffset);
IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
+ if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
+ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+ return 0;
+ }
+
if (flags & irfMarkFirst) {
firstGlyph = currGlyph;
}
--- icu-52.1.orig/source/layout/IndicRearrangementProcessor2.cpp
+++ icu-52.1/source/layout/IndicRearrangementProcessor2.cpp
@@ -43,6 +43,11 @@ le_uint16 IndicRearrangementProcessor2::
le_uint16 newState = SWAPW(entry->newStateIndex); // index to the new state
IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
+ if (currGlyph < 0 || currGlyph >= glyphStorage.getGlyphCount()) {
+ success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+ return 0;
+ }
+
if (flags & irfMarkFirst) {
firstGlyph = currGlyph;
}
--- icu-52.1.orig/source/layout/LigatureSubstProc.cpp
+++ icu-52.1/source/layout/LigatureSubstProc.cpp
@@ -48,7 +48,7 @@ ByteOffset LigatureSubstitutionProcessor
const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
ByteOffset newState = SWAPW(entry->newStateOffset);
- le_int16 flags = SWAPW(entry->flags);
+ le_uint16 flags = SWAPW(entry->flags);
if (flags & lsfSetComponent) {
if (++m >= nComponents) {
--- icu-52.1.orig/source/layout/StateTableProcessor.cpp
+++ icu-52.1/source/layout/StateTableProcessor.cpp
@@ -60,6 +60,7 @@ void StateTableProcessor::process(LEGlyp
if (currGlyph == glyphCount) {
// XXX: How do we handle EOT vs. EOL?
classCode = classCodeEOT;
+ break;
} else {
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphStorage[currGlyph]);
--- icu-52.1.orig/source/layout/StateTableProcessor2.cpp
+++ icu-52.1/source/layout/StateTableProcessor2.cpp
@@ -78,6 +78,7 @@ void StateTableProcessor2::process(LEGly
if (currGlyph == glyphCount || currGlyph == -1) {
// XXX: How do we handle EOT vs. EOL?
classCode = classCodeEOT;
+ break;
} else {
LEGlyphID gid = glyphStorage[currGlyph];
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
@@ -109,6 +110,7 @@ void StateTableProcessor2::process(LEGly
if (currGlyph == glyphCount || currGlyph == -1) {
// XXX: How do we handle EOT vs. EOL?
classCode = classCodeEOT;
+ break;
} else {
LEGlyphID gid = glyphStorage[currGlyph];
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
@@ -146,6 +148,7 @@ void StateTableProcessor2::process(LEGly
if (currGlyph == glyphCount || currGlyph == -1) {
// XXX: How do we handle EOT vs. EOL?
classCode = classCodeEOT;
+ break;
} else if(currGlyph > glyphCount) {
// note if > glyphCount, we've run off the end (bad font)
currGlyph = glyphCount;
@@ -186,6 +189,7 @@ void StateTableProcessor2::process(LEGly
if (currGlyph == glyphCount || currGlyph == -1) {
// XXX: How do we handle EOT vs. EOL?
classCode = classCodeEOT;
+ break;
} else {
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(glyphStorage[currGlyph]);
if (glyphCode == 0xFFFF) {
--- icu-52.1.orig/source/layout/StateTables.h
+++ icu-52.1/source/layout/StateTables.h
@@ -101,7 +101,7 @@ typedef le_uint8 EntryTableIndex;
struct StateEntry
{
ByteOffset newStateOffset;
- le_int16 flags;
+ le_uint16 flags;
};
typedef le_uint16 EntryTableIndex2;
|