aboutsummaryrefslogtreecommitdiffstats
path: root/prog/mutation_test.go
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2025-09-09 12:09:02 +0200
committerAlexander Potapenko <glider@google.com>2025-09-09 18:27:31 +0000
commit5ac84ab421465f8f15ac9350f9f33a4416b4b3b7 (patch)
tree4bd25bbaef09bb2a4fa31877862e8d2f20b17d1f /prog/mutation_test.go
parentd291dd2d58a1885c00a60561048b6ceb1bf1206a (diff)
prog: pkg/compiler: docs: introduce the `no_squash` attribute
The `no_squash` per-syscall attribute prevents the fuzzer from generating squashed arguments to a particular syscall. This is particularly helpful for pseudo-syscalls with elaborate arguments that are hard to reason about when they are squashed - e.g. for syz_kvm_add_vcpu() that takes a SYZOS program as an input. I've considered an alternative solution that prohibits ANY for all pseudo-syscalls. But there is a bunch of existing programs (both the tests and the repros) for syscalls like syz_mount_image() for which the benefit of not passing ANY is not immediately obvious. I therefore decided to go with an explicit attribute that can later be enforced for every pseudo-syscall at compile time.
Diffstat (limited to 'prog/mutation_test.go')
-rw-r--r--prog/mutation_test.go26
1 files changed, 26 insertions, 0 deletions
diff --git a/prog/mutation_test.go b/prog/mutation_test.go
index 1cd18656e..d9734b482 100644
--- a/prog/mutation_test.go
+++ b/prog/mutation_test.go
@@ -165,6 +165,32 @@ func TestMutateArgument(t *testing.T) {
}
}
+func TestMutateNoSquash(t *testing.T) {
+ target := initTargetTest(t, "test", "64")
+ p, err := target.Deserialize([]byte(`mutate_no_squash(&(0x7f0000000000)={0x1, 0x2, 0x3, 0x4, "5e9ce23b"})`), Strict)
+ if err != nil {
+ t.Fatal(err)
+ }
+ rs := rand.NewSource(0)
+ r := newRand(target, rs)
+ ctx := &mutator{
+ p: p,
+ r: r,
+ ncalls: 1,
+ ct: target.DefaultChoiceTable(),
+ opts: DefaultMutateOpts,
+ }
+
+ // squashAny should not mutate the program.
+ for i := 0; i < 100; i++ {
+ p1 := p.Clone()
+ ctx.p = p1
+ if ctx.squashAny() {
+ t.Fatalf("squashAny mutated a no_squash call: %s", p1.Serialize())
+ }
+ }
+}
+
func TestSizeMutateArg(t *testing.T) {
target, rs, iters := initRandomTargetTest(t, "test", "64")
r := newRand(target, rs)