From a0ee610de2477f592dae2e278f13dea64e35f90d Mon Sep 17 00:00:00 2001 From: chenyiyuan Date: Thu, 7 Dec 2023 13:02:32 +0000 Subject: [PATCH] Fix module literal problem in literal tag verification Description: Fix module literal problem in literal tag verification && GETTER / SETTER literal tag verification support ISSUE: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/I8MNLS?from=project-issue Signed-off-by: chenyiyuan Change-Id: I4a089cbd0ecb39404009a2e1c36f838a48a6e5ee --- BUILD.gn | 1 + verifier/tests/utils.cpp | 26 ++++++++++ verifier/tests/utils.h | 3 ++ verifier/tests/verify_constant_pool_tests.cpp | 49 ++++++------------- verifier/verifier.cpp | 31 ++++++++++-- verifier/verifier.h | 13 ++++- 6 files changed, 82 insertions(+), 41 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index 687c3f58f4..0a79626ff3 100755 --- a/BUILD.gn +++ b/BUILD.gn @@ -315,6 +315,7 @@ if (!ark_standalone_build) { "$ark_root/libpandafile/tests:host_unittest", "$ark_root/libziparchive/tests:host_unittest", "$ark_root/platforms/tests:host_unittest", + "$ark_root/verifier/tests:host_unittest", ] } diff --git a/verifier/tests/utils.cpp b/verifier/tests/utils.cpp index 0c03bf5b8d..a09c0c55ee 100644 --- a/verifier/tests/utils.cpp +++ b/verifier/tests/utils.cpp @@ -15,6 +15,7 @@ #include "utils.h" #include +#include #include "utils/logger.h" namespace panda::verifier { @@ -31,4 +32,29 @@ void GenerateModifiedAbc(const std::vector &buffer, const std::st abc_file.close(); } +void ConvertToLittleEndian(std::vector &inner_id, const uint32_t &id) +{ + std::vector bytes; + for (int i = 0; i < sizeof(uint32_t); ++i) { + unsigned char byte = static_cast((id >> (i * 8)) & 0xff); + inner_id.push_back(byte); + } +} + +void ModifyBuffer(std::unordered_map &literal_map, std::vector &buffer) +{ + for (const auto &literal : literal_map) { + size_t literal_id = literal.first; + std::vector inner_id; + ConvertToLittleEndian(inner_id, literal.second); + for (size_t i = literal_id; i < buffer.size(); ++i) { + if (buffer[i] == inner_id[0] && buffer[i+1] == inner_id[1]) { + buffer[i] = buffer[i + 1]; + buffer[i + 1] = buffer[i + 2]; + break; + } + } + } +} + } // namespace panda::verifier \ No newline at end of file diff --git a/verifier/tests/utils.h b/verifier/tests/utils.h index 420c38c4b5..5a1f0954ab 100644 --- a/verifier/tests/utils.h +++ b/verifier/tests/utils.h @@ -18,9 +18,12 @@ #include #include +#include namespace panda::verifier { void GenerateModifiedAbc(const std::vector &buffer, const std::string &filename); + void ConvertToLittleEndian(std::vector &inner_literal_id, const uint32_t &id); + void ModifyBuffer(std::unordered_map &inner_literal_map, std::vector &buffer); } // namespace panda::verifier #endif diff --git a/verifier/tests/verify_constant_pool_tests.cpp b/verifier/tests/verify_constant_pool_tests.cpp index 8112dc689c..57d3ee116b 100644 --- a/verifier/tests/verify_constant_pool_tests.cpp +++ b/verifier/tests/verify_constant_pool_tests.cpp @@ -15,9 +15,11 @@ #include "verifier.h" +#include #include #include #include +#include #include "file.h" #include "utils.h" @@ -299,26 +301,23 @@ HWTEST_F(VerifierConstantPool, verifier_constant_pool_007, TestSize.Level1) HWTEST_F(VerifierConstantPool, verifier_constant_pool_008, TestSize.Level1) { const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_constant_pool_content.abc"; + std::vector literal_ids; { panda::verifier::Verifier ver {base_file_name}; ver.CollectIdInfos(); EXPECT_TRUE(ver.VerifyConstantPoolContent()); + std::copy(ver.literal_ids_.begin(), ver.literal_ids_.end(), std::back_inserter(literal_ids)); } std::ifstream base_file(base_file_name, std::ios::binary); EXPECT_TRUE(base_file.is_open()); std::vector buffer(std::istreambuf_iterator(base_file), {}); - size_t literal_id = 0x2f8; // The known literal_id in the abc file + unsigned char invalid_tag = 0x5c; // a invalid tag - unsigned char tag = 0x05; // The literal tag of string in the abc file - unsigned char new_tag = 0x5c; // a invalid tag - - for (size_t i = literal_id; i < buffer.size(); ++i) { - if (buffer[i] == tag) { - buffer[i] = new_tag; - break; - } + for (const auto &literal_id : literal_ids) { + size_t tag_off = static_cast(literal_id) + sizeof(uint32_t); + buffer[tag_off] = invalid_tag; } const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_008.abc"; @@ -383,29 +382,19 @@ HWTEST_F(VerifierConstantPool, verifier_constant_pool_009, TestSize.Level1) HWTEST_F(VerifierConstantPool, verifier_constant_pool_010, TestSize.Level1) { const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_literal_array.abc"; + std::unordered_map inner_literal_map; { panda::verifier::Verifier ver {base_file_name}; ver.CollectIdInfos(); EXPECT_TRUE(ver.VerifyConstantPoolContent()); + inner_literal_map.insert(ver.inner_literal_map_.begin(), ver.inner_literal_map_.end()); } std::ifstream base_file(base_file_name, std::ios::binary); EXPECT_TRUE(base_file.is_open()); std::vector buffer(std::istreambuf_iterator(base_file), {}); - size_t literal_id = 0x578; // The known literal_id in the abc file - - // The known literal_id in the literal array of the abc file - std::vector inner_literal_id = {0xe9, 0x04}; - std::vector new_literal_id = {0xaa, 0xaa}; - - for (size_t i = literal_id; i < buffer.size(); ++i) { - if (buffer[i] == inner_literal_id[0] && buffer[i+1] == inner_literal_id[1]) { - buffer[i] = new_literal_id[0]; - buffer[i + 1] = new_literal_id[1]; - break; - } - } + ModifyBuffer(inner_literal_map, buffer); const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_010.abc"; GenerateModifiedAbc(buffer, target_file_name); @@ -427,29 +416,19 @@ HWTEST_F(VerifierConstantPool, verifier_constant_pool_010, TestSize.Level1) HWTEST_F(VerifierConstantPool, verifier_constant_pool_011, TestSize.Level1) { const std::string base_file_name = GRAPH_TEST_ABC_DIR "test_literal_array.abc"; + std::unordered_map inner_method_map; { panda::verifier::Verifier ver {base_file_name}; ver.CollectIdInfos(); EXPECT_TRUE(ver.VerifyConstantPoolContent()); + inner_method_map.insert(ver.inner_method_map_.begin(), ver.inner_method_map_.end()); } std::ifstream base_file(base_file_name, std::ios::binary); EXPECT_TRUE(base_file.is_open()); std::vector buffer(std::istreambuf_iterator(base_file), {}); - size_t literal_id = 0x57a; // The known literal_id in the abc file - - // The known method_id in the literal array of the abc file - std::vector method_id = {0xcc, 0x02}; - std::vector new_method_id = {0xff, 0xff}; - - for (size_t i = literal_id; i < buffer.size(); ++i) { - if (buffer[i] == method_id[0] && buffer[i+1] == method_id[1]) { - buffer[i] = new_method_id[0]; - buffer[i + 1] = new_method_id[1]; - break; - } - } + ModifyBuffer(inner_method_map, buffer); const std::string target_file_name = GRAPH_TEST_ABC_DIR "verifier_constant_pool_011.abc"; GenerateModifiedAbc(buffer, target_file_name); diff --git a/verifier/verifier.cpp b/verifier/verifier.cpp index a7ee0417db..7f9fa5fe05 100644 --- a/verifier/verifier.cpp +++ b/verifier/verifier.cpp @@ -51,7 +51,7 @@ void Verifier::CollectIdInfos() } GetMethodIds(); GetLiteralIds(); - CheckConstantPool(verifier::ActionType::COLLECTMETHODIDS); + CheckConstantPool(verifier::ActionType::COLLECTINFOS); } bool Verifier::VerifyChecksum() @@ -182,8 +182,8 @@ bool Verifier::CheckConstantPoolActions(const verifier::ActionType type, panda_f case verifier::ActionType::CHECKCONSTPOOLCONTENT: { return CheckConstantPoolMethodContent(method_id); } - case verifier::ActionType::COLLECTMETHODIDS: { - if (!std::binary_search(method_ids_.begin(), method_ids_.end(), method_id)) { + case verifier::ActionType::COLLECTINFOS: { + if (std::find(method_ids_.begin(), method_ids_.end(), method_id) == method_ids_.end()) { method_ids_.emplace_back(method_id); } return true; @@ -194,6 +194,15 @@ bool Verifier::CheckConstantPoolActions(const verifier::ActionType type, panda_f } } +void Verifier::CollectModuleLiteralId(const panda_file::File::EntityId &field_id) +{ + panda_file::FieldDataAccessor field_accessor(*file_, field_id); + const auto literal_id = field_accessor.GetValue().value(); + if (std::find(literal_ids_.begin(), literal_ids_.end(), literal_id) != literal_ids_.end()) { + module_literals_.insert(literal_id); + } +} + bool Verifier::CheckConstantPool(const verifier::ActionType type) { const auto class_idx = file_->GetClasses(); @@ -214,6 +223,11 @@ bool Verifier::CheckConstantPool(const verifier::ActionType type) if (!check_res) { return false; } + if (type == verifier::ActionType::COLLECTINFOS) { + class_accessor.EnumerateFields([&](panda_file::FieldDataAccessor &field_accessor) -> void { + CollectModuleLiteralId(field_accessor.GetFieldId()); + }); + } } } @@ -354,6 +368,8 @@ bool Verifier::VerifySingleLiteralArray(const panda_file::File::EntityId &litera } case panda_file::LiteralTag::INTEGER: case panda_file::LiteralTag::FLOAT: + case panda_file::LiteralTag::GETTER: + case panda_file::LiteralTag::SETTER: case panda_file::LiteralTag::GENERATORMETHOD: case panda_file::LiteralTag::LITERALBUFFERINDEX: case panda_file::LiteralTag::ASYNCGENERATORMETHOD: { @@ -388,6 +404,7 @@ bool Verifier::VerifySingleLiteralArray(const panda_file::File::EntityId &litera } case panda_file::LiteralTag::METHOD: { const auto value = static_cast(panda_file::helpers::Read(&sp)); + inner_method_map_.emplace(literal_id.GetOffset(), value); if (!VerifyMethodIdInLiteralArray(value)) { return false; } @@ -395,6 +412,7 @@ bool Verifier::VerifySingleLiteralArray(const panda_file::File::EntityId &litera } case panda_file::LiteralTag::LITERALARRAY: { const auto value = static_cast(panda_file::helpers::Read(&sp)); + inner_literal_map_.emplace(literal_id.GetOffset(), value); if (!VerifyLiteralIdInLiteralArray(value)) { return false; } @@ -409,11 +427,16 @@ bool Verifier::VerifySingleLiteralArray(const panda_file::File::EntityId &litera return true; } +bool Verifier::IsModuleLiteralId(const panda_file::File::EntityId &id) const +{ + return module_literals_.find(id.GetOffset()) != module_literals_.end(); +} + bool Verifier::VerifyLiteralArrays() { for (const auto &arg_literal_id : literal_ids_) { const auto literal_id = panda_file::File::EntityId(arg_literal_id); - if (!VerifySingleLiteralArray(literal_id)) { + if (!IsModuleLiteralId(literal_id) && !VerifySingleLiteralArray(literal_id)) { return false; } } diff --git a/verifier/verifier.h b/verifier/verifier.h index cb93137133..81981b0759 100644 --- a/verifier/verifier.h +++ b/verifier/verifier.h @@ -17,6 +17,8 @@ #define VERIFIER_VERIFIER_H #include +#include +#include #include "bytecode_instruction_enum_gen.h" #include "bytecode_instruction-inl.h" @@ -35,7 +37,7 @@ enum class ActionType { CHECKCONSTPOOL, CHECKCONSTPOOLIDX, CHECKCONSTPOOLCONTENT, - COLLECTMETHODIDS, + COLLECTINFOS, }; class Verifier { @@ -50,9 +52,15 @@ public: bool VerifyRegisterIndex(); bool VerifyConstantPoolIndex(); bool VerifyConstantPoolContent(); + + std::vector literal_ids_; + std::unordered_map inner_literal_map_; + std::unordered_map inner_method_map_; + private: void GetMethodIds(); void GetLiteralIds(); + void CollectModuleLiteralId(const panda_file::File::EntityId &field_id); bool CheckConstantPool(verifier::ActionType type); size_t GetVRegCount(const BytecodeInstruction &bc_ins); bool CheckConstantPoolActions(const verifier::ActionType type, panda_file::File::EntityId method_id); @@ -65,6 +73,7 @@ private: bool VerifyMethodIdInLiteralArray(const uint32_t &id); bool VerifyStringIdInLiteralArray(const uint32_t &id); bool VerifyLiteralIdInLiteralArray(const uint32_t &id); + bool IsModuleLiteralId(const panda_file::File::EntityId &id) const; bool VerifySingleLiteralArray(const panda_file::File::EntityId &literal_id); bool VerifyLiteralArrays(); bool VerifyStringId(const BytecodeInstruction &bc_ins, const panda_file::File::EntityId &method_id); @@ -80,7 +89,7 @@ private: std::unique_ptr file_; std::vector method_ids_; - std::vector literal_ids_; + std::unordered_set module_literals_; static constexpr size_t DEFAULT_ARGUMENT_NUMBER = 3; static constexpr uint32_t FILE_CONTENT_OFFSET = 12U; }; -- Gitee