diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-02-16 22:13:09 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-02-16 22:13:09 +0000 |
commit | 5cbd07cfc80ef5aa054347443a3bb419381c7423 (patch) | |
tree | f548e640ad238d6f0a7cd3f677f08e77c5cb92e3 | |
parent | 6abd1f95fb7796efc3391d51dbc9ffc3b3733ecb (diff) | |
parent | e8c4bf1365d555e6f11d64e3d7939b30438247da (diff) | |
download | minikin-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.cpp | 24 | ||||
-rw-r--r-- | tests/unittest/CmapCoverageTest.cpp | 48 |
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) { |