diff options
| author | Ethan Graham <ethangraham@google.com> | 2025-09-15 13:05:17 +0000 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2025-09-22 09:11:54 +0000 |
| commit | 6c7b65699dcfc2e93d2e7917f6b0e7bab99f2a26 (patch) | |
| tree | 8e1083c4b07c45f2be11b5b924a1d5c64d0e6e77 /prog/rand.go | |
| parent | f333ae936f1859d357b8efc744915fe7927a6c5d (diff) | |
prog: add specialized mutation for KFuzzTest calls
Internal kernel functions (and as a result KFuzzTest) have stricter
contracts than system calls. For this reason, we must avoid mutating
the following cases:
- Length arguments not matching the length of the related buffer.
- Strings not being null-terminated.
Add special cases for KFuzzTest calls that avoids these situations.
Signed-off-by: Ethan Graham <ethangraham@google.com>
Diffstat (limited to 'prog/rand.go')
| -rw-r--r-- | prog/rand.go | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/prog/rand.go b/prog/rand.go index 957cf7112..b06cc1a90 100644 --- a/prog/rand.go +++ b/prog/rand.go @@ -28,6 +28,7 @@ type randGen struct { target *Target inGenerateResource bool patchConditionalDepth int + genKFuzzTest bool recDepth map[string]int } @@ -354,7 +355,9 @@ func (r *randGen) randString(s *state, t *BufferType) []byte { buf.Write([]byte{byte(r.Intn(256))}) } } - if r.oneOf(100) == t.NoZ { + // We always null-terminate strings that are inputs to KFuzzTest calls to + // avoid false-positive buffer overflow reports. + if r.oneOf(100) == t.NoZ || r.genKFuzzTest { buf.Write([]byte{0}) } return buf.Bytes() @@ -609,6 +612,16 @@ func (r *randGen) generateParticularCall(s *state, meta *Syscall) (calls []*Call panic(fmt.Sprintf("generating no_generate call: %v", meta.Name)) } c := MakeCall(meta, nil) + // KFuzzTest calls restrict mutation and generation. Since calls to + // generateParticularCall can be recursive, we save the previous value, and + // set it true. + if c.Meta.Attrs.KFuzzTest { + tmp := r.genKFuzzTest + r.genKFuzzTest = true + defer func() { + r.genKFuzzTest = tmp + }() + } c.Args, calls = r.generateArgs(s, meta.Args, DirIn) moreCalls, _ := r.patchConditionalFields(c, s) r.target.assignSizesCall(c) |
