Loading libs/androidfw/LoadedArsc.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -212,7 +212,7 @@ const LoadedPackage* LoadedArsc::GetPackageForId(uint32_t resid) const { static bool VerifyType(const Chunk& chunk) { ATRACE_CALL(); const ResTable_type* header = chunk.header<ResTable_type>(); const ResTable_type* header = chunk.header<ResTable_type, kResTableTypeMinSize>(); const size_t entry_count = dtohl(header->entryCount); if (entry_count > std::numeric_limits<uint16_t>::max()) { Loading Loading @@ -533,7 +533,7 @@ std::unique_ptr<LoadedPackage> LoadedPackage::Load(const Chunk& chunk) { } break; case RES_TABLE_TYPE_TYPE: { const ResTable_type* type = child_chunk.header<ResTable_type>(); const ResTable_type* type = child_chunk.header<ResTable_type, kResTableTypeMinSize>(); if (type == nullptr) { LOG(ERROR) << "Chunk RES_TABLE_TYPE_TYPE is too small."; return {}; Loading libs/androidfw/include/androidfw/Chunk.h +2 −2 Original line number Diff line number Diff line Loading @@ -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 <typename T> template <typename T, size_t MinSize = sizeof(T)> inline const T* header() const { if (header_size() >= sizeof(T)) { if (header_size() >= MinSize) { return reinterpret_cast<const T*>(device_chunk_); } return nullptr; Loading libs/androidfw/include/androidfw/ResourceTypes.h +11 −2 Original line number Diff line number Diff line Loading @@ -1392,10 +1392,19 @@ 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. */ Loading tools/aapt2/unflatten/BinaryResourceParser.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -313,7 +313,9 @@ bool BinaryResourceParser::ParseType(const ResourceTablePackage* package, return false; } const ResTable_type* type = ConvertTo<ResTable_type>(chunk); // Specify a manual size, because ResTable_type contains ResTable_config, which changes // a lot and has its own code to handle variable size. const ResTable_type* type = ConvertTo<ResTable_type, kResTableTypeMinSize>(chunk); if (!type) { context_->GetDiagnostics()->Error(DiagMessage(source_) << "corrupt ResTable_type chunk"); Loading tools/aapt2/unflatten/ResChunkPullParser.h +2 −2 Original line number Diff line number Diff line Loading @@ -78,9 +78,9 @@ class ResChunkPullParser { std::string error_; }; template <typename T> template <typename T, size_t MinSize = sizeof(T)> inline static const T* ConvertTo(const android::ResChunk_header* chunk) { if (util::DeviceToHost16(chunk->headerSize) < sizeof(T)) { if (util::DeviceToHost16(chunk->headerSize) < MinSize) { return nullptr; } return reinterpret_cast<const T*>(chunk); Loading Loading
libs/androidfw/LoadedArsc.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -212,7 +212,7 @@ const LoadedPackage* LoadedArsc::GetPackageForId(uint32_t resid) const { static bool VerifyType(const Chunk& chunk) { ATRACE_CALL(); const ResTable_type* header = chunk.header<ResTable_type>(); const ResTable_type* header = chunk.header<ResTable_type, kResTableTypeMinSize>(); const size_t entry_count = dtohl(header->entryCount); if (entry_count > std::numeric_limits<uint16_t>::max()) { Loading Loading @@ -533,7 +533,7 @@ std::unique_ptr<LoadedPackage> LoadedPackage::Load(const Chunk& chunk) { } break; case RES_TABLE_TYPE_TYPE: { const ResTable_type* type = child_chunk.header<ResTable_type>(); const ResTable_type* type = child_chunk.header<ResTable_type, kResTableTypeMinSize>(); if (type == nullptr) { LOG(ERROR) << "Chunk RES_TABLE_TYPE_TYPE is too small."; return {}; Loading
libs/androidfw/include/androidfw/Chunk.h +2 −2 Original line number Diff line number Diff line Loading @@ -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 <typename T> template <typename T, size_t MinSize = sizeof(T)> inline const T* header() const { if (header_size() >= sizeof(T)) { if (header_size() >= MinSize) { return reinterpret_cast<const T*>(device_chunk_); } return nullptr; Loading
libs/androidfw/include/androidfw/ResourceTypes.h +11 −2 Original line number Diff line number Diff line Loading @@ -1392,10 +1392,19 @@ 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. */ Loading
tools/aapt2/unflatten/BinaryResourceParser.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -313,7 +313,9 @@ bool BinaryResourceParser::ParseType(const ResourceTablePackage* package, return false; } const ResTable_type* type = ConvertTo<ResTable_type>(chunk); // Specify a manual size, because ResTable_type contains ResTable_config, which changes // a lot and has its own code to handle variable size. const ResTable_type* type = ConvertTo<ResTable_type, kResTableTypeMinSize>(chunk); if (!type) { context_->GetDiagnostics()->Error(DiagMessage(source_) << "corrupt ResTable_type chunk"); Loading
tools/aapt2/unflatten/ResChunkPullParser.h +2 −2 Original line number Diff line number Diff line Loading @@ -78,9 +78,9 @@ class ResChunkPullParser { std::string error_; }; template <typename T> template <typename T, size_t MinSize = sizeof(T)> inline static const T* ConvertTo(const android::ResChunk_header* chunk) { if (util::DeviceToHost16(chunk->headerSize) < sizeof(T)) { if (util::DeviceToHost16(chunk->headerSize) < MinSize) { return nullptr; } return reinterpret_cast<const T*>(chunk); Loading