summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Android Build Merger (Role) <noreply-android-build-merger@google.com> 2018-04-13 20:34:53 +0000
committer Android Build Merger (Role) <noreply-android-build-merger@google.com> 2018-04-13 20:34:53 +0000
commit80e36faa72653ebd41b7963809f69c9a5f62d1f6 (patch)
tree9ac72b213fed8f758cfb1f70d8bfdc450ef38306
parent1890afd456cd6fa182aeeb5efacf159c1115d5ef (diff)
parenta509e771ba2480da5c79e12db1e86b6f2fb1d221 (diff)
[automerger] ResStringPool: Fix security vulnerability am: 7e54c3f261 am: 98e2d2ec50 am: 24a89da344 am: d85632ae40 am: 927b3357fa am: 79d0fb2530 am: a509e771ba
Change-Id: I48bf9619571a30e6f5ea5bad503a3805e0821a75
-rw-r--r--libs/androidfw/ResourceTypes.cpp18
1 files changed, 18 insertions, 0 deletions
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 7cb42169cd76..f608d7bf0681 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -457,6 +457,22 @@ status_t ResStringPool::setTo(const void* data, size_t size, bool copyData)
uninit();
+ // The chunk must be at least the size of the string pool header.
+ if (size < sizeof(ResStringPool_header)) {
+ LOG_ALWAYS_FATAL("Bad string block: data size %zu is too small to be a string block", size);
+ return (mError=BAD_TYPE);
+ }
+
+ // The data is at least as big as a ResChunk_header, so we can safely validate the other
+ // header fields.
+ // `data + size` is safe because the source of `size` comes from the kernel/filesystem.
+ if (validate_chunk(reinterpret_cast<const ResChunk_header*>(data), sizeof(ResStringPool_header),
+ reinterpret_cast<const uint8_t*>(data) + size,
+ "ResStringPool_header") != NO_ERROR) {
+ LOG_ALWAYS_FATAL("Bad string block: malformed block dimensions");
+ return (mError=BAD_TYPE);
+ }
+
const bool notDeviceEndian = htods(0xf0) != 0xf0;
if (copyData || notDeviceEndian) {
@@ -468,6 +484,8 @@ status_t ResStringPool::setTo(const void* data, size_t size, bool copyData)
data = mOwnedData;
}
+ // The size has been checked, so it is safe to read the data in the ResStringPool_header
+ // data structure.
mHeader = (const ResStringPool_header*)data;
if (notDeviceEndian) {