From 136fd0764faf7a588b4a1b479d7a8cc6fe18fcc6 Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Fri, 3 Mar 2017 13:50:21 -0800 Subject: AAPT2: Fix parsing ResTable_type ResTable_type's size changes due to it containing ResTable_config. Make sure we check for the minimum size required to read it. Bug: 35861796 Test: Manual (don't have an integration test harness setup yet) Change-Id: Ifb0cd1d732625f59835c8ed0449adb78129636de --- libs/androidfw/include/androidfw/Chunk.h | 4 ++-- libs/androidfw/include/androidfw/ResourceTypes.h | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'libs/androidfw/include') diff --git a/libs/androidfw/include/androidfw/Chunk.h b/libs/androidfw/include/androidfw/Chunk.h index e87b94087450..89b588e2b2e9 100644 --- a/libs/androidfw/include/androidfw/Chunk.h +++ b/libs/androidfw/include/androidfw/Chunk.h @@ -48,9 +48,9 @@ class Chunk { // Returns the size of the header. Caller need not worry about endianness. inline size_t header_size() const { return dtohs(device_chunk_->headerSize); } - template + template inline const T* header() const { - if (header_size() >= sizeof(T)) { + if (header_size() >= MinSize) { return reinterpret_cast(device_chunk_); } return nullptr; diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h index d982a353b013..306ff9a7c42c 100644 --- a/libs/androidfw/include/androidfw/ResourceTypes.h +++ b/libs/androidfw/include/androidfw/ResourceTypes.h @@ -1391,11 +1391,20 @@ struct ResTable_type // Offset from header where ResTable_entry data starts. uint32_t entriesStart; - - // Configuration this collection of entries is designed for. + + // Configuration this collection of entries is designed for. This must always be last. ResTable_config config; }; +// The minimum size required to read any version of ResTable_type. +constexpr size_t kResTableTypeMinSize = + sizeof(ResTable_type) - sizeof(ResTable_config) + sizeof(ResTable_config::size); + +// Assert that the ResTable_config is always the last field. This poses a problem for extending +// ResTable_type in the future, as ResTable_config is variable (over different releases). +static_assert(sizeof(ResTable_type) == offsetof(ResTable_type, config) + sizeof(ResTable_config), + "ResTable_config must be last field in ResTable_type"); + /** * An entry in a ResTable_type with the flag `FLAG_SPARSE` set. */ -- cgit v1.2.3-59-g8ed1b