mirror of
https://github.com/morluto/rea.git
synced 2026-10-26 17:35:11 +00:00
fix(managed): report malformed PE layouts as invalid input (#2194)
* fix(managed): report malformed PE layouts as invalid input readManagedPeLayout raises ManagedReaderFailure for DOS, COFF and section header failures such as section data past EOF. Those escaped the managed inspectors, so ManagedStaticProvider wrapped them as ProviderAdapterError and the CLI and MCP reported execution_failure with advice to run rea doctor. Map format failures to an invalid_format input issue carrying the reader's detail, as inspect-pe-resources and inspect-go-binary do. Fixes #2191 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(managed): route unmappable PE layouts through one input error inspect-managed-native-boundaries caught a layout-level ManagedReaderFailure itself and returned an empty malformed inspection with exit 0, while the other managed operations now report the same bytes as invalid input. Let the layout failure reach the provider's invalid_format mapping; metadata failures after a readable layout still return malformed coverage. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
df2c08b546
commit
90e37f4152
3 files changed
+51
-9
No files matched your search
@@ -121,15 +121,8 @@ export const inspectManagedNativeBoundariesBytes = (
|
||||
bytes: Buffer,
|
||||
target: BinaryTarget,
|
||||
): ManagedNativeBoundaryInspection => {
|
||||
let pe: ManagedPeLayout;
|
||||
try {
|
||||
pe = readManagedPeLayout(bytes);
|
||||
} catch (cause: unknown) {
|
||||
if (!(cause instanceof ManagedReaderFailure)) throw cause;
|
||||
return emptyInspection(target, bytes, "malformed", {
|
||||
issues: [cause.issue],
|
||||
});
|
||||
}
|
||||
// An unmappable PE layout is invalid input for every managed operation.
|
||||
const pe = readManagedPeLayout(bytes);
|
||||
if (pe.cli === null)
|
||||
return emptyInspection(
|
||||
target,
|
||||
|
||||
@@ -22,6 +22,7 @@ import type { BinaryTarget } from "../domain/binaryTargetTypes.js";
|
||||
import {
|
||||
AnalysisCancelledError,
|
||||
AnalysisCapabilityUnavailableError,
|
||||
AnalysisInputError,
|
||||
} from "../domain/analysisErrorCore.js";
|
||||
import { EvidenceIntegrityError } from "../domain/evidenceErrors.js";
|
||||
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
||||
@@ -38,6 +39,7 @@ import { inspectManagedArtifactBytes } from "./ManagedArtifactInspector.js";
|
||||
import { inspectManagedMembersBytes } from "./ManagedMemberInspector.js";
|
||||
import { inspectManagedNativeBoundariesBytes } from "./ManagedNativeBoundaryInspector.js";
|
||||
import { RegularFileCleanupFailure } from "../application/RegularFileRead.js";
|
||||
import { ManagedReaderFailure } from "./ManagedReaderFailure.js";
|
||||
import {
|
||||
hashManagedSource,
|
||||
managedCleanupError,
|
||||
@@ -135,6 +137,20 @@ class ManagedStaticClient implements AnalysisClient {
|
||||
if (cause instanceof AnalysisError) return err(cause);
|
||||
if (options?.signal?.aborted === true)
|
||||
return err(new AnalysisCancelledError(operation));
|
||||
// A PE header or section table the reader cannot map is malformed input.
|
||||
if (
|
||||
cause instanceof ManagedReaderFailure &&
|
||||
cause.issue.code !== "resource-limit"
|
||||
)
|
||||
return err(
|
||||
new AnalysisInputError(operation, { cause }, [
|
||||
{
|
||||
path: ["path"],
|
||||
reason: "invalid_format",
|
||||
message: `Selected artifact ${this.target.path}: ${cause.issue.detail}`,
|
||||
},
|
||||
]),
|
||||
);
|
||||
return err(
|
||||
new ProviderAdapterError(MANAGED_STATIC_PROVIDER.id, operation, {
|
||||
cause,
|
||||
|
||||
@@ -307,3 +307,36 @@ cliTest(
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
cliTest(
|
||||
"managed CLI reports a section table past EOF as invalid input",
|
||||
async ({ cli }) => {
|
||||
const root = await createTestTempDirectory("rea-managed-cli-sections-");
|
||||
const path = join(root, "fixture.dll");
|
||||
const bytes = buildManagedPeFixture();
|
||||
const pe = bytes.readUInt32LE(0x3c);
|
||||
const sections = pe + 24 + bytes.readUInt16LE(pe + 20);
|
||||
bytes.writeUInt32LE(bytes.length + 0x1000, sections + 20);
|
||||
await writeFile(path, bytes);
|
||||
for (const command of [
|
||||
"inspect-managed-artifact",
|
||||
"inspect-managed-members",
|
||||
"inspect-managed-native-boundaries",
|
||||
]) {
|
||||
const result = await cli.run({ arguments: [command, path, "--json"] });
|
||||
expect(result.exitCode).toBe(1);
|
||||
expect(result.json).toMatchObject({
|
||||
code: "invalid_request",
|
||||
details: {
|
||||
issues: [
|
||||
{
|
||||
path: ["path"],
|
||||
reason: "invalid_format",
|
||||
message: expect.stringContaining("pe.section-data"),
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
Reference in new issue
Block a user