diff options
| -rw-r--r-- | pkg/osutil/osutil.go | 12 | ||||
| -rw-r--r-- | pkg/osutil/osutil_test.go | 10 | ||||
| -rw-r--r-- | syz-fuzzer/fuzzer.go | 4 | ||||
| -rw-r--r-- | tools/syz-linter/linter.go | 2 |
4 files changed, 25 insertions, 3 deletions
diff --git a/pkg/osutil/osutil.go b/pkg/osutil/osutil.go index 478c091dc..a619f9169 100644 --- a/pkg/osutil/osutil.go +++ b/pkg/osutil/osutil.go @@ -17,6 +17,7 @@ import ( "sync" "syscall" "time" + _ "unsafe" // required to use go:linkname ) const ( @@ -337,3 +338,14 @@ func Abs(path string) string { } return filepath.Join(wd, path) } + +// MonotonicNano returns monotonic time in nanoseconds from some unspecified point in time. +// Useful mostly to measure time intervals. +// This function should be used inside of tested VMs b/c time.Now may reject to use monotonic time +// if the fuzzer messes with system time (sets time past Y2157, see comments in time/time.go). +// This is a hacky way to use the private runtime function. +// If this ever breaks, we can either provide specializations for different Go versions +// using build tags, or fall back to time.Now. +// +//go:linkname MonotonicNano runtime.nanotime +func MonotonicNano() time.Duration diff --git a/pkg/osutil/osutil_test.go b/pkg/osutil/osutil_test.go index 713a62c14..7d5913b4a 100644 --- a/pkg/osutil/osutil_test.go +++ b/pkg/osutil/osutil_test.go @@ -9,6 +9,7 @@ import ( "path/filepath" "strings" "testing" + "time" ) func TestIsExist(t *testing.T) { @@ -119,3 +120,12 @@ func TestCopyFiles(t *testing.T) { }) } } + +func TestMonotonicNano(t *testing.T) { + start := MonotonicNano() + time.Sleep(100 * time.Millisecond) + diff := MonotonicNano() - start + if diff <= 0 || diff > 10*time.Second { + t.Fatalf("diff %v", diff) + } +} diff --git a/syz-fuzzer/fuzzer.go b/syz-fuzzer/fuzzer.go index f539de6f6..fb7f57b30 100644 --- a/syz-fuzzer/fuzzer.go +++ b/syz-fuzzer/fuzzer.go @@ -347,11 +347,11 @@ func (tool *FuzzerTool) exchangeDataCall(needProgs int, results []executionResul a.Results = append(a.Results, tool.convertExecutionResult(result)) } r := &rpctype.ExchangeInfoReply{} - start := time.Now() + start := osutil.MonotonicNano() if err := tool.manager.Call("Manager.ExchangeInfo", a, r); err != nil { log.SyzFatalf("Manager.ExchangeInfo call failed: %v", err) } - latency = time.Since(start) + latency = osutil.MonotonicNano() - start if needProgs != len(r.Requests) { log.SyzFatalf("manager returned wrong number of requests: %v/%v", needProgs, len(r.Requests)) } diff --git a/tools/syz-linter/linter.go b/tools/syz-linter/linter.go index 76168c7c9..542d040e6 100644 --- a/tools/syz-linter/linter.go +++ b/tools/syz-linter/linter.go @@ -139,7 +139,7 @@ var ( noPeriodComment = regexp.MustCompile(`^// [A-Z][a-z].+[a-z]$`) lowerCaseComment = regexp.MustCompile(`^// [a-z]+ `) onelineExceptions = regexp.MustCompile(`// want \"|http:|https:`) - specialComment = regexp.MustCompile(`//go:generate|//go:build|//go:embed|// nolint:`) + specialComment = regexp.MustCompile(`//go:generate|//go:build|//go:embed|//go:linkname|// nolint:`) ) // checkStringLenCompare checks for string len comparisons with 0. |
