summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaph Levien <raph@google.com>2015-11-30 15:04:59 -0800
committerRaph Levien <raph@google.com>2015-12-07 17:58:12 +0000
commit6299a6ba13906c695f7a4f6748f7bc5856a110e5 (patch)
tree3cfc5b953fddd4f30422cc176a3fd6956c3d0163
parentd5804e3937a961736e5cef0e8a70eacf91ee00bb (diff)
downloadandroid_frameworks_minikin-6299a6ba13906c695f7a4f6748f7bc5856a110e5.tar.gz
android_frameworks_minikin-6299a6ba13906c695f7a4f6748f7bc5856a110e5.tar.bz2
android_frameworks_minikin-6299a6ba13906c695f7a4f6748f7bc5856a110e5.zip
Avoid integer overflows in parsing fonts
A malformed TTF can cause size calculations to overflow. This patch checks the maximum reasonable value so that the total size fits in 32 bits. It also adds some explicit casting to avoid possible technical undefined behavior when parsing sized unsigned values. Bug: 25645298 Change-Id: Id4716132041a6f4f1fbb73ec4e445391cf7d9616 (cherry picked from commit 183c9ec2800baa2ce099ee260c6cbc6121cf1274)
-rw-r--r--libs/minikin/CmapCoverage.cpp9
1 files changed, 6 insertions, 3 deletions
diff --git a/libs/minikin/CmapCoverage.cpp b/libs/minikin/CmapCoverage.cpp
index 4156d69..8be45d1 100644
--- a/libs/minikin/CmapCoverage.cpp
+++ b/libs/minikin/CmapCoverage.cpp
@@ -30,11 +30,12 @@ namespace android {
// These could perhaps be optimized to use __builtin_bswap16 and friends.
static uint32_t readU16(const uint8_t* data, size_t offset) {
- return data[offset] << 8 | data[offset + 1];
+ return ((uint32_t)data[offset]) << 8 | ((uint32_t)data[offset + 1]);
}
static uint32_t readU32(const uint8_t* data, size_t offset) {
- return data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3];
+ return ((uint32_t)data[offset]) << 24 | ((uint32_t)data[offset + 1]) << 16 |
+ ((uint32_t)data[offset + 2]) << 8 | ((uint32_t)data[offset + 3]);
}
static void addRange(vector<uint32_t> &coverage, uint32_t start, uint32_t end) {
@@ -101,11 +102,13 @@ static bool getCoverageFormat12(vector<uint32_t>& coverage, const uint8_t* data,
const size_t kGroupSize = 12;
const size_t kStartCharCodeOffset = 0;
const size_t kEndCharCodeOffset = 4;
+ const size_t kMaxNGroups = 0xfffffff0 / kGroupSize; // protection against overflow
+ // For all values < kMaxNGroups, kFirstGroupOffset + nGroups * kGroupSize fits in 32 bits.
if (kFirstGroupOffset > size) {
return false;
}
uint32_t nGroups = readU32(data, kNGroupsOffset);
- if (kFirstGroupOffset + nGroups * kGroupSize > size) {
+ if (nGroups >= kMaxNGroups || kFirstGroupOffset + nGroups * kGroupSize > size) {
return false;
}
for (uint32_t i = 0; i < nGroups; i++) {