mirror of
https://github.com/morluto/rea.git
synced 2026-11-12 17:59:08 +00:00
* fix(verifiers): retain native cleanup ownership on failure * fix(verification): load cleanup fixtures through the module resolver CodeQL's local threat model treats file contents passed to vm.SourceTextModule as user-controlled code execution. Import the real verifier modules and redirect their dependencies to static mocks instead of compiling script text read from disk. * fix(verifiers): own CLI and MCP process families * fix(verifiers): retire workspaces after cleanup retry --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
150 lines
3.7 KiB
JavaScript
150 lines
3.7 KiB
JavaScript
import * as fs from "node:fs/promises";
|
|
import { promisify } from "node:util";
|
|
|
|
const graph = {
|
|
target_sha256: "a".repeat(64),
|
|
seed: "0x1000",
|
|
procedures: [],
|
|
nodes: [
|
|
{
|
|
id: "c",
|
|
evidence_id: "ev_" + "b".repeat(64),
|
|
operation: { opcode: "CALL", inputs: [] },
|
|
},
|
|
{
|
|
id: "p",
|
|
evidence_id: "ev_" + "b".repeat(64),
|
|
kind: "parameter",
|
|
parameter: { ordinal: 0 },
|
|
},
|
|
{
|
|
id: "r",
|
|
evidence_id: "ev_" + "b".repeat(64),
|
|
operation: { opcode: "RETURN", inputs: [{ location: "0x2000" }] },
|
|
},
|
|
],
|
|
edges: [
|
|
{
|
|
kind: "argument-binding",
|
|
source: "c",
|
|
target: "p",
|
|
status: "derived",
|
|
input_index: 1,
|
|
},
|
|
{
|
|
kind: "parameter-use",
|
|
source: "p",
|
|
target: "r",
|
|
status: "derived",
|
|
input_index: 0,
|
|
},
|
|
{
|
|
kind: "return-binding",
|
|
source: "r",
|
|
target: "c",
|
|
status: "derived",
|
|
input_index: 1,
|
|
},
|
|
],
|
|
};
|
|
const evidence = {
|
|
operation: "trace_native_values",
|
|
provider: { id: "rea-workflow" },
|
|
analysis_profile: {
|
|
provider: { id: "rea-workflow" },
|
|
parameters: {
|
|
upstream_analysis_profile: {
|
|
provider: { id: "ghidra" },
|
|
digest: "c".repeat(64),
|
|
},
|
|
},
|
|
},
|
|
normalized_result: graph,
|
|
};
|
|
|
|
/** Shared stand-in state for one native verifier cleanup process. */
|
|
export const nativeCleanupState = {
|
|
fault: "none",
|
|
events: [],
|
|
workspace: undefined,
|
|
clientCloseCalls: 0,
|
|
transportCloseCalls: 0,
|
|
primary: new Error("inert connection failure"),
|
|
cleanup: new Error("inert client close failure"),
|
|
transportFailure: new Error("inert transport close failure"),
|
|
};
|
|
|
|
export const mkdir = fs.mkdir;
|
|
export const readdir = fs.readdir;
|
|
export const mkdtemp = async (...args) => {
|
|
const directory = await fs.mkdtemp(...args);
|
|
nativeCleanupState.workspace = directory;
|
|
return directory;
|
|
};
|
|
export const rm = async (...args) => {
|
|
nativeCleanupState.events.push("rm");
|
|
return fs.rm(...args);
|
|
};
|
|
|
|
export const execFile = Object.assign(
|
|
() => {
|
|
throw new Error("No child process authorized");
|
|
},
|
|
{
|
|
[promisify.custom]: async () => {
|
|
if (nativeCleanupState.fault === "early")
|
|
throw nativeCleanupState.primary;
|
|
return { stdout: JSON.stringify(evidence) };
|
|
},
|
|
},
|
|
);
|
|
|
|
export class Client {
|
|
async connect() {
|
|
nativeCleanupState.events.push("connect");
|
|
throw nativeCleanupState.primary;
|
|
}
|
|
async close() {
|
|
nativeCleanupState.events.push("client.close");
|
|
nativeCleanupState.clientCloseCalls += 1;
|
|
if (
|
|
["client", "both"].includes(nativeCleanupState.fault) &&
|
|
nativeCleanupState.clientCloseCalls === 1
|
|
)
|
|
throw nativeCleanupState.cleanup;
|
|
}
|
|
}
|
|
|
|
export class StdioClientTransport {
|
|
async close() {
|
|
nativeCleanupState.events.push("transport.close");
|
|
nativeCleanupState.transportCloseCalls += 1;
|
|
if (
|
|
["transport", "both"].includes(nativeCleanupState.fault) &&
|
|
nativeCleanupState.transportCloseCalls === 1
|
|
)
|
|
throw nativeCleanupState.transportFailure;
|
|
}
|
|
}
|
|
|
|
export const parseEvidence = (value) => value;
|
|
export const analysisProfileSchema = { parse: (value) => value };
|
|
export const nativeValueTraceSchema = { parse: (value) => value };
|
|
export function requireMcpEvidenceBundle() {}
|
|
export function requireMcpLifecycleResult() {}
|
|
export function requireMcpOutput() {}
|
|
export function verifyGhidraBoundaries() {}
|
|
export function verifyLegacyValueScopeSnapshot() {}
|
|
export function verifyGhidraProjectIdentity() {}
|
|
export function verifyGhidraSocketBoundary() {}
|
|
|
|
export async function createOwnedMcpStdioTransport() {
|
|
return new StdioClientTransport();
|
|
}
|
|
export async function createVerifierCommands() {
|
|
return {
|
|
exec: (...args) => promisify(execFile)(...args),
|
|
close: async () => {},
|
|
};
|
|
}
|