mirror of
https://gitee.com/openharmony/arkcompiler_runtime_core
synced 2024-10-07 13:54:17 +00:00
!786 Fix module literal problem in literal tag verification
Merge pull request !786 from OneYuan/module_literal
This commit is contained in:
commit
426ec9b91d
1
BUILD.gn
1
BUILD.gn
@ -317,6 +317,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",
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "utils.h"
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include "utils/logger.h"
|
||||
|
||||
namespace panda::verifier {
|
||||
@ -31,4 +32,29 @@ void GenerateModifiedAbc(const std::vector<unsigned char> &buffer, const std::st
|
||||
abc_file.close();
|
||||
}
|
||||
|
||||
void ConvertToLittleEndian(std::vector<unsigned char> &inner_id, const uint32_t &id)
|
||||
{
|
||||
std::vector<unsigned char> bytes;
|
||||
for (int i = 0; i < sizeof(uint32_t); ++i) {
|
||||
unsigned char byte = static_cast<unsigned char>((id >> (i * 8)) & 0xff);
|
||||
inner_id.push_back(byte);
|
||||
}
|
||||
}
|
||||
|
||||
void ModifyBuffer(std::unordered_map<uint32_t, uint32_t> &literal_map, std::vector<unsigned char> &buffer)
|
||||
{
|
||||
for (const auto &literal : literal_map) {
|
||||
size_t literal_id = literal.first;
|
||||
std::vector<unsigned char> 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
|
@ -18,9 +18,12 @@
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace panda::verifier {
|
||||
void GenerateModifiedAbc(const std::vector<unsigned char> &buffer, const std::string &filename);
|
||||
void ConvertToLittleEndian(std::vector<unsigned char> &inner_literal_id, const uint32_t &id);
|
||||
void ModifyBuffer(std::unordered_map<uint32_t, uint32_t> &inner_literal_map, std::vector<unsigned char> &buffer);
|
||||
} // namespace panda::verifier
|
||||
|
||||
#endif
|
||||
|
@ -15,9 +15,11 @@
|
||||
|
||||
#include "verifier.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <gtest/gtest.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#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<uint32_t> 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<unsigned char> buffer(std::istreambuf_iterator<char>(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<size_t>(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<uint32_t, uint32_t> 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<unsigned char> buffer(std::istreambuf_iterator<char>(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<unsigned char> inner_literal_id = {0xe9, 0x04};
|
||||
std::vector<unsigned char> 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<uint32_t, uint32_t> 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<unsigned char> buffer(std::istreambuf_iterator<char>(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<unsigned char> method_id = {0xcc, 0x02};
|
||||
std::vector<unsigned char> 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);
|
||||
|
@ -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<uint32_t>().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<uint32_t>(panda_file::helpers::Read<sizeof(uint32_t)>(&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<uint32_t>(panda_file::helpers::Read<sizeof(uint32_t)>(&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;
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
#define VERIFIER_VERIFIER_H
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#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<uint32_t> literal_ids_;
|
||||
std::unordered_map<uint32_t, uint32_t> inner_literal_map_;
|
||||
std::unordered_map<uint32_t, uint32_t> 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<const panda_file::File> file_;
|
||||
std::vector<panda_file::File::EntityId> method_ids_;
|
||||
std::vector<uint32_t> literal_ids_;
|
||||
std::unordered_set<uint32_t> module_literals_;
|
||||
static constexpr size_t DEFAULT_ARGUMENT_NUMBER = 3;
|
||||
static constexpr uint32_t FILE_CONTENT_OFFSET = 12U;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user