diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-03-15 17:00:16 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-03-15 17:00:16 +0000 |
commit | a4ff69b3554b569a04e4327ca22b9dad262d7141 (patch) | |
tree | f548e640ad238d6f0a7cd3f677f08e77c5cb92e3 | |
parent | 46abf7e01c369a92731ba3a9c01532ebbc7c77e5 (diff) | |
parent | 594e33f93a3a35cf2cbfda67edc0d80ee1423327 (diff) | |
download | minikin-oreo-m2-release.tar.gz |
Snap for 4603989 from 594e33f93a3a35cf2cbfda67edc0d80ee1423327 to oc-m2-releaseandroid-8.1.0_r33android-8.1.0_r30android-8.1.0_r26android-8.1.0_r25android-8.1.0_r20oreo-m2-s3-releaseoreo-m2-s2-releaseoreo-m2-s1-releaseoreo-m2-release
Change-Id: Ifd3d40f768331bbd9402e2149de733b0a1f5ced6
-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) { |