fix(native): refuse truncated executable headers at target admission

Target admission accepted a thin Mach-O after reading only its magic and
CPU type, so a 12-byte prefix opened as a valid arm64 executable and the
first provider query failed as a generic execution failure. ELF headers
were likewise accepted after 20 bytes, and a FAT file whose selected slice
lies beyond its end was admitted.

Require the complete fixed header (Mach-O 28 or 32 bytes, ELF 52 or 64),
Mach-O load commands that fit in the file, and a selected FAT slice within
the file, checking commitments against the file size rather than the
probed prefix. Each refusal names the failed constraint.

Fixes #1189

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kaoru0822
2026-10-09 03:51:37 +00:00
parent e1afbc1914
commit 0b04d384cc
6 changed files with 137 additions and 20 deletions
+5 -2
View File
@@ -237,6 +237,9 @@ const readExecutableMetadata = async (
const prefix = Buffer.alloc(4096);
const prefixRead = await handle.read(prefix, 0, prefix.length, 0);
const bytes = prefix.subarray(0, prefixRead.bytesRead);
// Header commitments such as Mach-O load commands and FAT slices are
// checked against the whole file, not the probed prefix.
const fileSize = (await handle.stat()).size;
if (bytes.length >= 2 && bytes[0] === 0x4d && bytes[1] === 0x5a) {
const offset = mzWindowsHeaderOffset(bytes);
if (offset !== null) {
@@ -251,7 +254,6 @@ const readExecutableMetadata = async (
? bytes.readUInt16LE(24) + bytes.readUInt16LE(6) * 4
: 0;
const headerBytes = bytes.length >= 28 ? bytes.readUInt16LE(8) * 16 : 0;
const fileSize = (await handle.stat()).size;
if (
tableEnd > bytes.length &&
tableEnd <= headerBytes &&
@@ -279,11 +281,12 @@ const readExecutableMetadata = async (
return parseExecutableHeader(
header.subarray(0, headerRead.bytesRead),
hostArchitecture,
fileSize,
);
}
}
}
return parseExecutableHeader(bytes, hostArchitecture);
return parseExecutableHeader(bytes, hostArchitecture, fileSize);
};
const readPeMetadata = async (