阶段 C 步骤 8:vm 读侧型号匹配 + SHA-256 校验。

- vm/Image.cpp:执行器侧 SHA-256 实现(与 compiler 各一份)、fill_model_id、
  model_id()/model_matches()/sha_ok();data_len 不含 SHA 尾
- Machine::create:sha256 不匹配 → 'image sha256 mismatch';型号不匹配 →
  'image model mismatch'(内建 kModelName=STATOR/kModelVersion=1),均拒绝
- vm_test:手拼映像填型号(修越界读 bug)+ compiler::sha256 填尾(95 断言);
  新增篡改拒绝(sha256 mismatch)与型号不匹配(重算 SHA 后 model mismatch)用例
- 验证:line1 正常执行 Q=1;篡改一字节 → 执行器 'image sha256 mismatch' 拒绝;ctest 12/12
This commit is contained in:
2026-08-21 22:29:33 +08:00
parent 5fccbadaa8
commit b13585711a
4 changed files with 246 additions and 4 deletions
+70
View File
@@ -13,6 +13,7 @@
#include "compiler/Codegen.h"
#include "compiler/Linker.h"
#include "compiler/Project.h"
#include "compiler/Stb.h"
#include "compiler/Typecheck.h"
#include "isa/Encode.h"
#include "isa/Instr.h"
@@ -155,6 +156,16 @@ static std::vector<uint8_t> hand_image(const std::vector<vm::ConstEntry>& consts
for (size_t i = 0; i < data.size(); ++i) {
b[off_data + i] = data[i];
}
// 型号标识(STATOR1+ 真实 SHA-256 尾(用 compiler 实现填)
const char* mid = "STATOR1";
for (size_t i = 0; i < 32; ++i) {
b[72 + i] = i < 7 ? static_cast<uint8_t>(mid[i]) : 0;
}
uint8_t digest[32];
compiler::sha256(b.data(), b.size() - 32, digest);
for (int i = 0; i < 32; ++i) {
b[b.size() - 32 + i] = digest[i];
}
return b;
}
@@ -428,6 +439,64 @@ static bool test_bad_const() {
return true;
}
// ---- 10. 12.13 校验:SHA 篡改拒绝 + 型号不匹配拒绝 ----
static bool test_verify() {
std::string err;
vm::Machine m;
// 正常映像可跑
CHECK(make_machine("tests/cases/01_empty_main", &m, &err));
CHECK(m.run_cycle() == vm::Fault::None);
// SHA 篡改:改一字节 → create 拒绝
{
const std::string toml = std::string(REPO_ROOT) + "/tests/cases/01_empty_main/project.toml";
compiler::Project p;
CHECK(compiler::parse_project(toml, &p, &err));
std::vector<compiler::SourceUnit> units;
for (const std::string& f : compiler::compile_files(p)) {
compiler::SourceUnit u;
CHECK(compiler::load_unit(p.base_dir + "/" + f, &u, &err));
units.push_back(std::move(u));
}
compiler::LinkResult link;
CHECK(compiler::link_project(p, units, &link, &err));
compiler::MachineConfig cfg;
CHECK(cfg.load(std::string(REPO_ROOT) + "/compiler/machine.toml", &err));
std::vector<uint8_t> img;
CHECK(compiler::codegen_project(p, units, link, cfg, &img, &err));
img[100] ^= 0x01; // 篡改代码段一字节
vm::Machine bad;
CHECK(!vm::Machine::create(img, &bad, &err));
CHECK(err.find("sha256 mismatch") != std::string::npos);
}
// 型号不匹配:手拼映像改型号(重算 SHA,仅型号不一致)→ create 拒绝
{
const std::vector<vm::ConstEntry> consts;
const std::vector<HFunc> funcs = {{
{
isa::enc_ret(),
},
8,
}};
std::vector<uint8_t> img = hand_image(consts, funcs);
for (int i = 0; i < 5; ++i) {
img[72 + i] = "OTHER"[i];
}
uint8_t digest[32];
compiler::sha256(img.data(), img.size() - 32, digest);
for (int i = 0; i < 32; ++i) {
img[img.size() - 32 + i] = digest[i];
}
vm::Machine bad;
CHECK(!vm::Machine::create(img, &bad, &err));
CHECK(err.find("model mismatch") != std::string::npos);
}
return true;
}
int main() {
if (!test_hand_scalar()) return 1;
if (!test_hand_call()) return 1;
@@ -438,6 +507,7 @@ int main() {
if (!test_determinism()) return 1;
if (!test_step()) return 1;
if (!test_bad_const()) return 1;
if (!test_verify()) return 1;
std::printf("vm_test: %d checks passed\n", g_checks);
return 0;
}