From ab7e45a8d853978516b4c0f12a01d4e9b753ed20 Mon Sep 17 00:00:00 2001 From: Bharadwaj Kalandhabhatta Date: Thu, 6 Jul 2017 10:05:31 -0700 Subject: Added more functionality to dex file tracking. Added functions that poison parts of String Data Items of Dex Files. Also added a function that poisons less parts of a Code Item , which reduces possibly unnecessary information. Bug: 37754950 Test: export ART_DEX_FILE_ACCESS_TRACKING=true && m -j && m -j SANITIZE_TARGET=address SANITIZE_LITE=true test-art-host Change-Id: Icfd3db36e52beef4631f3ffd221d0a019cdd5308 --- runtime/dex_file_tracking_registrar.cc | 70 +++++++++++++++++++++++++++++++++- runtime/dex_file_tracking_registrar.h | 9 +++++ 2 files changed, 77 insertions(+), 2 deletions(-) (limited to 'runtime') diff --git a/runtime/dex_file_tracking_registrar.cc b/runtime/dex_file_tracking_registrar.cc index d958568e55..341158671b 100644 --- a/runtime/dex_file_tracking_registrar.cc +++ b/runtime/dex_file_tracking_registrar.cc @@ -58,6 +58,15 @@ enum DexTrackingType { // Additionally unpoisons the entire Code Item when method is a class // initializer. kCodeItemNonInsnsNoClinitTracking, + // Poisons the size and offset information along with the first instruction. + // This is so that accessing multiple instructions while accessing a code item + // once will not trigger unnecessary accesses. + kCodeItemStartTracking, + // Poisons all String Data Items of a Dex Files when set. + kStringDataItemTracking, + // Poisons the first byte of the utf16_size value and the first byte of the + // data section for all String Data Items of a Dex File. + kStringDataItemStartTracking, // Poisons based on a custom tracking system which can be specified in // SetDexSections kCustomTracking, @@ -89,10 +98,21 @@ void DexFileTrackingRegistrar::SetDexSections() { SetAllInsnsRegistration(false); SetCodeItemRegistration("", false); break; + case kCodeItemStartTracking: + SetAllCodeItemStartRegistration(true); + break; + case kStringDataItemTracking: + SetAllStringDataRegistration(true); + break; + case kStringDataItemStartTracking: + SetAllStringDataStartRegistration(true); + break; case kCustomTracking: // TODO: Add/remove additional calls here to (un)poison sections of // dex_file_ break; + default: + break; } } } @@ -151,6 +171,28 @@ void DexFileTrackingRegistrar::SetAllCodeItemRegistration(bool should_poison) { } } +void DexFileTrackingRegistrar::SetAllCodeItemStartRegistration(bool should_poison) { + for (size_t classdef_ctr = 0; classdef_ctr < dex_file_->NumClassDefs(); ++classdef_ctr) { + const DexFile::ClassDef& cd = dex_file_->GetClassDef(classdef_ctr); + const uint8_t* class_data = dex_file_->GetClassData(cd); + if (class_data != nullptr) { + ClassDataItemIterator cdit(*dex_file_, class_data); + cdit.SkipAllFields(); + while (cdit.HasNextDirectMethod()) { + const DexFile::CodeItem* code_item = cdit.GetMethodCodeItem(); + if (code_item != nullptr) { + const void* code_item_begin = reinterpret_cast(code_item); + size_t code_item_start = reinterpret_cast(code_item); + size_t code_item_start_end = reinterpret_cast(&code_item->insns_[1]); + size_t code_item_start_size = code_item_start_end - code_item_start; + range_values_.push_back(std::make_tuple(code_item_begin, code_item_start_size, should_poison)); + } + cdit.Next(); + } + } + } +} + void DexFileTrackingRegistrar::SetAllInsnsRegistration(bool should_poison) { for (size_t classdef_ctr = 0; classdef_ctr < dex_file_->NumClassDefs(); ++classdef_ctr) { const DexFile::ClassDef& cd = dex_file_->GetClassDef(classdef_ctr); @@ -186,8 +228,7 @@ void DexFileTrackingRegistrar::SetCodeItemRegistration(const char* class_name, b if (code_item != nullptr && strcmp(methodid_name, class_name) == 0) { const void* code_item_begin = reinterpret_cast(code_item); size_t code_item_size = DexFile::GetCodeItemSize(*code_item); - range_values_.push_back( - std::make_tuple(code_item_begin, code_item_size, should_poison)); + range_values_.push_back(std::make_tuple(code_item_begin, code_item_size, should_poison)); } cdit.Next(); } @@ -195,6 +236,31 @@ void DexFileTrackingRegistrar::SetCodeItemRegistration(const char* class_name, b } } +void DexFileTrackingRegistrar::SetAllStringDataStartRegistration(bool should_poison) { + for (size_t stringid_ctr = 0; stringid_ctr < dex_file_->NumStringIds(); ++stringid_ctr) { + const DexFile::StringId & string_id = dex_file_->GetStringId(StringIndex(stringid_ctr)); + const void* string_data_begin = reinterpret_cast(dex_file_->Begin() + string_id.string_data_off_); + // Data Section of String Data Item + const void* string_data_data_begin = reinterpret_cast(dex_file_->GetStringData(string_id)); + range_values_.push_back(std::make_tuple(string_data_begin, 1, should_poison)); + range_values_.push_back(std::make_tuple(string_data_data_begin, 1, should_poison)); + } +} + +void DexFileTrackingRegistrar::SetAllStringDataRegistration(bool should_poison) { + size_t map_offset = dex_file_->GetHeader().map_off_; + auto map_list = reinterpret_cast(dex_file_->Begin() + map_offset); + for (size_t map_ctr = 0; map_ctr < map_list->size_; ++map_ctr) { + const DexFile::MapItem& map_item = map_list->list_[map_ctr]; + if (map_item.type_ == DexFile::kDexTypeStringDataItem) { + const DexFile::MapItem& next_map_item = map_list->list_[map_ctr + 1]; + const void* string_data_begin = reinterpret_cast(dex_file_->Begin() + map_item.offset_); + size_t string_data_size = next_map_item.offset_ - map_item.offset_; + range_values_.push_back(std::make_tuple(string_data_begin, string_data_size, should_poison)); + } + } +} + } // namespace tracking } // namespace dex } // namespace art diff --git a/runtime/dex_file_tracking_registrar.h b/runtime/dex_file_tracking_registrar.h index b0fa275b38..5c0e0f50ab 100644 --- a/runtime/dex_file_tracking_registrar.h +++ b/runtime/dex_file_tracking_registrar.h @@ -54,6 +54,15 @@ class DexFileTrackingRegistrar { void SetAllInsnsRegistration(bool should_poison); // This function finds the code item of a class based on class name. void SetCodeItemRegistration(const char* class_name, bool should_poison); + // Sets the size and offset information along with first instruction in insns_ + // section of all code items. + void SetAllCodeItemStartRegistration(bool should_poison); + + // Set of functions concerning String Data Items of dex_file_ + void SetAllStringDataRegistration(bool should_poison); + // Sets the first byte of size value and data section of all string data + // items. + void SetAllStringDataStartRegistration(bool should_poison); // Contains tuples of all ranges of memory that need to be explicitly // (un)poisoned by the memory tool. -- cgit v1.2.3-59-g8ed1b