Guard BuildCallStub against argument-count overflow

The x64 frame math (0x20 + 8*stackArgs) and x86 arg buffer size grow with the
argument count. An absurdly large count could overflow int and produce a bogus
or negative frame. Add a MaxArguments (256) bound checked at the public entry —
far above any real calling convention — so the arithmetic stays in range. Add a
test asserting the cap is inclusive and count+1 throws.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
kbe
2026-07-21 22:10:33 +02:00
co-authored by Claude Opus 4.8
parent cb437ef9b5
commit b06a034072
2 changed files with 30 additions and 2 deletions
+14
View File
@@ -444,6 +444,20 @@ public class StubAssemblerTests
Create().BuildCallStub((IntPtr)0x10000000, (IntPtr)0x12345678, [], 4, (CallConvention)99));
}
[Fact]
public void Too_many_arguments_throws_before_frame_math_overflows()
{
// Guards the 0x20 + 8*stackArgs frame arithmetic against int overflow.
// MaxArguments is honored (accepted) and MaxArguments+1 is rejected.
var atCap = new nuint[StubAssembler.MaxArguments];
// At the cap the call still builds (cdecl x64), proving the bound is inclusive.
_ = Create().BuildCallStub((IntPtr)0x10000000, (IntPtr)0x10001000, atCap, 8, CallConvention.Cdecl);
var overCap = new nuint[StubAssembler.MaxArguments + 1];
Assert.Throws<ArgumentOutOfRangeException>(() =>
Create().BuildCallStub((IntPtr)0x10000000, (IntPtr)0x10001000, overCap, 8, CallConvention.Cdecl));
}
// ── No-FASM ─────────────────────────────────────────────────────────
[Fact]