summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-02-16 22:13:09 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-02-16 22:13:09 +0000
commit5cbd07cfc80ef5aa054347443a3bb419381c7423 (patch)
treef548e640ad238d6f0a7cd3f677f08e77c5cb92e3
parent6abd1f95fb7796efc3391d51dbc9ffc3b3733ecb (diff)
parente8c4bf1365d555e6f11d64e3d7939b30438247da (diff)
downloadminikin-oreo-m3-release.tar.gz
Merge cherrypicks of [3628702, 3628645, 3628777, 3628703, 3628704, 3628646, 3628647, 3627516, 3628742, 3628743, 3628744, 3628745, 3628746, 3628693, 3628694, 3628695, 3628696, 3628697, 3628698, 3628792, 3628793, 3628705, 3627458, 3628648, 3628649, 3628650, 3628651, 3628652, 3628653, 3628654, 3628655, 3628656, 3628794, 3628795, 3628796] into oc-m3-releaseandroid-8.1.0_r21oreo-m3-release
Change-Id: I3c5a18e4a4c610c21a37e82f3a0ac117e983b69a
-rw-r--r--libs/minikin/CmapCoverage.cpp24
-rw-r--r--tests/unittest/CmapCoverageTest.cpp48
2 files changed, 66 insertions, 6 deletions
diff --git a/libs/minikin/CmapCoverage.cpp b/libs/minikin/CmapCoverage.cpp
index c6318f5..78e7b0d 100644
--- a/libs/minikin/CmapCoverage.cpp
+++ b/libs/minikin/CmapCoverage.cpp
@@ -319,8 +319,12 @@ static bool getVSCoverage(std::vector<uint32_t>* out_ranges, const uint8_t* data
if (nonDefaultUVSTableRemaining < kHeaderSize) {
return false;
}
- const uint32_t numRecords = readU32(nonDefaultUVSTable, 0);
- if (numRecords * kUVSMappingRecordSize + kHeaderSize > nonDefaultUVSTableRemaining) {
+ const uint64_t numRecords = readU32(nonDefaultUVSTable, 0);
+ const uint64_t sizeToRead = numRecords * kUVSMappingRecordSize + kHeaderSize;
+ if (sizeToRead > nonDefaultUVSTableRemaining) {
+ if (sizeToRead > UINT_MAX) {
+ android_errorWriteLog(0x534e4554, "70808908");
+ }
return false;
}
for (uint32_t i = 0; i < numRecords; ++i) {
@@ -347,8 +351,12 @@ static bool getVSCoverage(std::vector<uint32_t>* out_ranges, const uint8_t* data
if (defaultUVSTableRemaining < kHeaderSize) {
return false;
}
- const uint32_t numRecords = readU32(defaultUVSTable, 0);
- if (numRecords * kUnicodeRangeRecordSize + kHeaderSize > defaultUVSTableRemaining) {
+ const uint64_t numRecords = readU32(defaultUVSTable, 0);
+ const uint64_t sizeToRead = numRecords * kUnicodeRangeRecordSize + kHeaderSize;
+ if (sizeToRead > defaultUVSTableRemaining) {
+ if (sizeToRead > UINT_MAX) {
+ android_errorWriteLog(0x534e4554, "70808908");
+ }
return false;
}
@@ -392,8 +400,12 @@ static void getCoverageFormat14(std::vector<std::unique_ptr<SparseBitSet>>* out,
return;
}
- uint32_t numRecords = readU32(data, kNumRecordOffset);
- if (numRecords == 0 || kHeaderSize + kRecordSize * numRecords > length) {
+ const uint64_t numRecords = readU32(data, kNumRecordOffset);
+ const uint64_t sizeToRead = kHeaderSize + kRecordSize * numRecords;
+ if (numRecords == 0 || sizeToRead > length) {
+ if (sizeToRead > UINT_MAX) {
+ android_errorWriteLog(0x534e4554, "70808908");
+ }
return;
}
diff --git a/tests/unittest/CmapCoverageTest.cpp b/tests/unittest/CmapCoverageTest.cpp
index fe2d7ba..590a363 100644
--- a/tests/unittest/CmapCoverageTest.cpp
+++ b/tests/unittest/CmapCoverageTest.cpp
@@ -988,6 +988,54 @@ TEST(CmapCoverageTest, TableSelection_brokenVSTable) {
SparseBitSet coverage = CmapCoverage::getCoverage(cmap.data(), cmap.size(), &vsTables);
ASSERT_TRUE(vsTables.empty());
}
+ {
+ // http://b/70808908
+ SCOPED_TRACE("OOB access due to integer overflow in non default UVS table");
+ std::vector<uint8_t> vsTable = buildCmapFormat14Table(
+ std::vector<VariationSelectorRecord>({{0xFE0F, {'a', 'a'}, {'b'}}}));
+ // 6 is the offset of the numRecords in the Cmap format14 subtable header.
+ writeU32(0x1745d174 /* 2^32 / kRecordSize(=11) */, vsTable.data(), 6);
+ CmapBuilder builder(2);
+ builder.appendTable(3, 1, cmap12Table);
+ builder.appendTable(VS_PLATFORM_ID, VS_ENCODING_ID, vsTable);
+ std::vector<uint8_t> cmap = builder.build();
+
+ std::vector<std::unique_ptr<SparseBitSet>> vsTables;
+ SparseBitSet coverage = CmapCoverage::getCoverage(cmap.data(), cmap.size(), &vsTables);
+ ASSERT_TRUE(vsTables.empty());
+ }
+ {
+ // http://b/70808908
+ SCOPED_TRACE("OOB access due to integer overflow in non default UVS table");
+ std::vector<uint8_t> vsTable = buildCmapFormat14Table(
+ std::vector<VariationSelectorRecord>({{0xFE0F, {'a', 'a'}, {'b'}}}));
+ // 29 is the offset of the numUVSMappings in the fist non defulat UVS table.
+ writeU32(0x33333333 /* 2^32 / kUVSMappingRecordSize(=5) */, vsTable.data(), 29);
+ CmapBuilder builder(2);
+ builder.appendTable(3, 1, cmap12Table);
+ builder.appendTable(VS_PLATFORM_ID, VS_ENCODING_ID, vsTable);
+ std::vector<uint8_t> cmap = builder.build();
+
+ std::vector<std::unique_ptr<SparseBitSet>> vsTables;
+ SparseBitSet coverage = CmapCoverage::getCoverage(cmap.data(), cmap.size(), &vsTables);
+ ASSERT_TRUE(vsTables.empty());
+ }
+ {
+ // http://b/70808908
+ SCOPED_TRACE("OOB access due to integer overflow in default UVS table");
+ std::vector<uint8_t> vsTable = buildCmapFormat14Table(
+ std::vector<VariationSelectorRecord>({{0xFE0F, {'a', 'a'}, {'b'}}}));
+ // 21 is the offset of the numUnicodeValueRanges in the fist defulat UVS table.
+ writeU32(0x40000000 /* 2^32 / kUnicodeRangeRecordSize(=4) */, vsTable.data(), 21);
+ CmapBuilder builder(2);
+ builder.appendTable(3, 1, cmap12Table);
+ builder.appendTable(VS_PLATFORM_ID, VS_ENCODING_ID, vsTable);
+ std::vector<uint8_t> cmap = builder.build();
+
+ std::vector<std::unique_ptr<SparseBitSet>> vsTables;
+ SparseBitSet coverage = CmapCoverage::getCoverage(cmap.data(), cmap.size(), &vsTables);
+ ASSERT_TRUE(vsTables.empty());
+ }
}
TEST(CmapCoverageTest, TableSelection_brokenVSTable_bestEffort) {