fix(verify): arm64 stack save, adaptive canary and host gating

Assisted-by: GLM 5.3
This commit is contained in:
2026-09-19 23:49:19 +02:00
parent 87b1081c53
commit 375182ef1f
25 changed files with 651 additions and 57 deletions
+68
View File
@@ -4,6 +4,8 @@
package verify
import (
"os"
"strings"
"testing"
)
@@ -65,6 +67,72 @@ func TestFuzzWideCopy(t *testing.T) {
}
}
// TestFuzzFuncSigWiderThanFrame pins the guard against a // func comment
// that declares more parameter bytes than the TEXT frame carries: before
// the guard, slicing the result area at paramsSize(sig) past the end of
// the argument block panicked the whole test binary.
func TestFuzzFuncSigWiderThanFrame(t *testing.T) {
k := loadBasic(t)
gt, err := GroundTruth("../testdata/verify/basic_amd64.s")
if err != nil {
t.Skipf("go tool asm unavailable: %v", err)
}
goCode, ok := gt["add"]
if !ok {
t.Skip("add not in ground truth")
}
// add carries $0-24; four int parameters declare 32 bytes.
sig := funcSig{
name: "add",
params: []param{
{name: "a", typ: "int"},
{name: "b", typ: "int"},
{name: "c", typ: "int"},
{name: "d", typ: "int"},
},
}
res := k.FuzzFunc("add", sig, goCode, 3, 42)
if res.OK() {
t.Fatal("expected the over-wide signature to fail the campaign")
}
if !strings.Contains(res.FirstFail, "parameter bytes") || !strings.Contains(res.FirstFail, "argument bytes") {
t.Errorf("FirstFail = %q, want a clear signature-versus-frame message", res.FirstFail)
}
}
// TestFuzzStringParam runs the differential fuzzer over a kernel whose
// only parameter is a string: the marshaller lays out a real two-word
// header (data pointer + length) and the comparison slices at
// paramsSize(sig) = 16, so the length word is input, not result.
func TestFuzzStringParam(t *testing.T) {
k := loadStrProbeKernel(t)
file := t.TempDir() + "/strprobe_amd64.s"
if err := os.WriteFile(file, []byte(strProbeSrc), 0o644); err != nil {
t.Fatalf("write kernel: %v", err)
}
gt, err := GroundTruth(file)
if err != nil {
t.Skipf("go tool asm unavailable: %v", err)
}
goCode, ok := gt["strProbe"]
if !ok {
t.Skip("strProbe not in ground truth")
}
sig, ok := parseFuncSig("// func strProbe(s string) int64")
if !ok {
t.Fatal("parseFuncSig failed")
}
res := k.FuzzFunc("strProbe", sig, goCode, 100, 42)
if !res.OK() {
t.Errorf("strProbe fuzz: %s", res)
}
}
func TestParseFuncSig(t *testing.T) {
tests := []struct {
comment string