mirror of
https://github.com/tailscale/tailscale.git
synced 2026-10-23 03:37:19 +09:00
fuzz: wire fuzzing to a standalone oss-fuzz script (#20862)
This change adds an entry point for oss-fuzz `fuzz/oss-fuzz.sh`, allowing us to wire in our current and future fuzzing into oss-fuzz without needing to update the google/oss-fuzz repo. Existing fuzzing was also reviewed with the following changes: * disco/disco_fuzzer.go renamed to disco/fuzz_test.go so that it can have a _test.go suffix and match the modern go fuzzing design. * net/stun/stun_fuzzer.go renamed to net/stun/fuzz_test.go similar to the above * Disco and stun recieved seeds for their fuzzing starts * All existing fuzzing was given a local round of testing, which resulted in a round trip fix for disco not handling a full zero node key. * Running and building fuzzing was removed from CI (build only). The fuzz seeds are validated in normal go testing, but the fuzzing itself will only happen if run manually or on oss-fuzz. Updates https://github.com/tailscale/corp/issues/46608 Change-Id: I47cb70169aefb02ac5a56220f26a6ec07fa135ee Signed-off-by: Mike Jensen <mikej@tailscale.com>
This commit is contained in:
1 parent
d9cc55e33b
commit
fae8f241bf
9 files changed
+218
-117
No files matched your search
@@ -3,18 +3,6 @@
|
||||
name: CI
|
||||
|
||||
env:
|
||||
# Our fuzz job, powered by OSS-Fuzz, fails periodically because we upgrade to
|
||||
# new Go versions very eagerly. OSS-Fuzz is a little more conservative, and
|
||||
# ends up being unable to compile our code.
|
||||
#
|
||||
# When this happens, we want to disable the fuzz target until OSS-Fuzz catches
|
||||
# up. However, we also don't want to forget to turn it back on when OSS-Fuzz
|
||||
# can once again build our code.
|
||||
#
|
||||
# This variable toggles the fuzz job between two modes:
|
||||
# - false: we expect fuzzing to be happy, and should report failure if it's not.
|
||||
# - true: we expect fuzzing is broken, and should report failure if it start working.
|
||||
TS_FUZZ_CURRENTLY_BROKEN: false
|
||||
# GOMODCACHE is the same definition on all OSes. Within the workspace, we use
|
||||
# toplevel directories "src" (for the checked out source code), and "gomodcache"
|
||||
# and other caches as siblings to follow.
|
||||
@@ -673,74 +661,6 @@ jobs:
|
||||
- name: test tailscale_go
|
||||
run: ./tool/go test -tags=tailscale_go,ts_enable_sockstats ./net/sockstats/...
|
||||
|
||||
|
||||
fuzz:
|
||||
# This target periodically breaks (see TS_FUZZ_CURRENTLY_BROKEN at the top
|
||||
# of the file), so it's more complex than usual: the 'build fuzzers' step
|
||||
# might fail, and depending on the value of 'TS_FUZZ_CURRENTLY_BROKEN', that
|
||||
# might or might not be fine. The steps after the build figure out whether
|
||||
# the success/failure is expected, and appropriately pass/fail the job
|
||||
# overall accordingly.
|
||||
#
|
||||
# Practically, this means that all steps after 'build fuzzers' must have an
|
||||
# explicit 'if' condition, because the default condition for steps is
|
||||
# 'success()', meaning "only run this if no previous steps failed".
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: build fuzzers
|
||||
id: build
|
||||
# As of 12 February 2026, this repo doesn't tag releases, so this commit
|
||||
# hash is just the tip of master.
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@f277aafb36f358582fdb24a41a9a52f2e097a2fd
|
||||
# continue-on-error makes steps.build.conclusion be 'success' even if
|
||||
# steps.build.outcome is 'failure'. This means this step does not
|
||||
# contribute to the job's overall pass/fail evaluation.
|
||||
continue-on-error: true
|
||||
with:
|
||||
oss-fuzz-project-name: 'tailscale'
|
||||
dry-run: false
|
||||
language: go
|
||||
- name: report unexpectedly broken fuzz build
|
||||
if: steps.build.outcome == 'failure' && env.TS_FUZZ_CURRENTLY_BROKEN != 'true'
|
||||
run: |
|
||||
echo "fuzzer build failed, see above for why"
|
||||
echo "if the failure is due to OSS-Fuzz not being on the latest Go yet,"
|
||||
echo "set TS_FUZZ_CURRENTLY_BROKEN=true in .github/workflows/test.yml"
|
||||
echo "to temporarily disable fuzzing until OSS-Fuzz works again."
|
||||
exit 1
|
||||
- name: report unexpectedly working fuzz build
|
||||
if: steps.build.outcome == 'success' && env.TS_FUZZ_CURRENTLY_BROKEN == 'true'
|
||||
run: |
|
||||
echo "fuzzer build succeeded, but we expect it to be broken"
|
||||
echo "please set TS_FUZZ_CURRENTLY_BROKEN=false in .github/workflows/test.yml"
|
||||
echo "to reenable fuzz testing"
|
||||
exit 1
|
||||
- name: run fuzzers
|
||||
id: run
|
||||
# Run the fuzzers whenever they're able to build, even if we're going to
|
||||
# report a failure because TS_FUZZ_CURRENTLY_BROKEN is set to the wrong
|
||||
# value.
|
||||
if: steps.build.outcome == 'success'
|
||||
# As of 12 February 2026, this repo doesn't tag releases, so this commit
|
||||
# hash is just the tip of master.
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@f277aafb36f358582fdb24a41a9a52f2e097a2fd
|
||||
with:
|
||||
oss-fuzz-project-name: 'tailscale'
|
||||
fuzz-seconds: 150
|
||||
dry-run: false
|
||||
language: go
|
||||
- name: Set artifacts_path in env (workaround for actions/upload-artifact#176)
|
||||
if: steps.run.outcome != 'success' && steps.build.outcome == 'success'
|
||||
run: |
|
||||
echo "artifacts_path=$(realpath .)" >> $GITHUB_ENV
|
||||
- name: upload crash
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
if: steps.run.outcome != 'success' && steps.build.outcome == 'success'
|
||||
with:
|
||||
name: artifacts
|
||||
path: ${{ env.artifacts_path }}/out/artifacts
|
||||
|
||||
depaware:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: gomod-cache
|
||||
@@ -904,7 +824,6 @@ jobs:
|
||||
- ios
|
||||
- wasm
|
||||
- tailscale_go
|
||||
- fuzz
|
||||
- depaware
|
||||
- go_generate
|
||||
- make_tidy
|
||||
@@ -1059,7 +978,6 @@ jobs:
|
||||
- ios
|
||||
- wasm
|
||||
- tailscale_go
|
||||
- fuzz
|
||||
- depaware
|
||||
- go_generate
|
||||
- make_tidy
|
||||
@@ -1105,7 +1023,6 @@ jobs:
|
||||
- windows
|
||||
- macos
|
||||
- wasm
|
||||
- fuzz
|
||||
- race-root-integration
|
||||
- privileged
|
||||
steps:
|
||||
|
||||
+7
-2
@@ -177,8 +177,13 @@ func parsePing(ver uint8, p []byte) (m *Ping, err error) {
|
||||
// Deliberately lax on longer-than-expected messages, for future
|
||||
// compatibility.
|
||||
if len(p) >= key.NodePublicRawLen {
|
||||
m.NodeKey = key.NodePublicFromRaw32(mem.B(p[:key.NodePublicRawLen]))
|
||||
m.Padding -= key.NodePublicRawLen
|
||||
// Skip all-zero trailing bytes: treat them as padding, not a NodeKey,
|
||||
// to match AppendMarshal (which omits zero keys).
|
||||
nk := key.NodePublicFromRaw32(mem.B(p[:key.NodePublicRawLen]))
|
||||
if !nk.IsZero() {
|
||||
m.NodeKey = nk
|
||||
m.Padding -= key.NodePublicRawLen
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
//go:build gofuzz
|
||||
|
||||
package disco
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
m, _ := Parse(data)
|
||||
|
||||
newBytes := m.AppendMarshal(data)
|
||||
parsedMarshall, _ := Parse(newBytes)
|
||||
|
||||
if m != parsedMarshall {
|
||||
panic("Parsing error")
|
||||
}
|
||||
return 1
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package disco
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func FuzzDiscoParse(f *testing.F) {
|
||||
// seeds from test cases in disco_test.go
|
||||
f.Add([]byte{0x1, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc})
|
||||
f.Add([]byte{0x6, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x2,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x1f, 0x0, 0x1, 0x2,
|
||||
0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11,
|
||||
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
|
||||
0x1f})
|
||||
f.Add([]byte{0x2, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb,
|
||||
0xc, 0xfe, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x12, 0x1a, 0xa})
|
||||
f.Add([]byte{0x5, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x2,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x1f, 0x0, 0x1, 0x2,
|
||||
0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11,
|
||||
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
|
||||
0x1f})
|
||||
f.Add([]byte{0x7, 0x0, 0x0, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x1e, 0x1f, 0x0, 0x1, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x1e, 0x1f, 0x0, 0x1, 0x2, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x1e, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7b, 0x0, 0x0,
|
||||
0x1, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x9a, 0xca, 0x0, 0x0, 0x0, 0x0, 0xd, 0xf8,
|
||||
0x47, 0x58, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff,
|
||||
0x1, 0x2, 0x3, 0x4, 0x2, 0x37, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x34, 0x56, 0x3, 0x15})
|
||||
f.Add([]byte{0x1, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb,
|
||||
0xc, 0x0, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e,
|
||||
0x1f, 0x0, 0x0, 0x0})
|
||||
f.Add([]byte{0x3, 0x0})
|
||||
f.Add([]byte{0x2, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb,
|
||||
0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x2, 0x3, 0x4,
|
||||
0x5, 0x4, 0xd2})
|
||||
f.Add([]byte{0x1, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb,
|
||||
0xc, 0x0, 0x0, 0x0})
|
||||
f.Add([]byte{0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff,
|
||||
0xff, 0x1, 0x2, 0x3, 0x4, 0x2, 0x37, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34, 0x56, 0x3, 0x15})
|
||||
f.Add([]byte{0x4, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2, 0x0, 0x1, 0x2,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x1f, 0x0, 0x1, 0x2,
|
||||
0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11,
|
||||
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
|
||||
0x1f})
|
||||
f.Add([]byte{0x9, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x1f, 0x0, 0x1, 0x2, 0x3, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x1f, 0x0, 0x1, 0x2, 0x0, 0x4, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x7b, 0x0, 0x0, 0x1, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x9a, 0xca, 0x0, 0x0, 0x0,
|
||||
0x0, 0xd, 0xf8, 0x47, 0x58, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0xff, 0xff, 0x1, 0x2, 0x3, 0x4, 0x2, 0x37, 0x20, 0x1, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x34, 0x56, 0x3, 0x15})
|
||||
f.Add([]byte{0x8, 0x0, 0x0, 0x1, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x1e, 0x1f, 0x0, 0x1, 0x2, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x1e, 0x1f, 0x0, 0x0, 0x0, 0x1})
|
||||
f.Add([]byte{0x1, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb,
|
||||
0xc, 0x0, 0x1, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1e,
|
||||
0x1f})
|
||||
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
m, err := Parse(data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
b := m.AppendMarshal(nil)
|
||||
m2, _ := Parse(b)
|
||||
if !reflect.DeepEqual(m, m2) {
|
||||
t.Fatalf("round-trip mismatch for %T: %v - %v", m, m, m2)
|
||||
}
|
||||
})
|
||||
}
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) Tailscale Inc & contributors
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
# This script builds all of Tailscale's OSS-Fuzz fuzz targets.
|
||||
#
|
||||
# It is invoked by the google/oss-fuzz project configuration for tailscale:
|
||||
# projects/tailscale/build.sh runs: bash -x ./fuzz/oss-fuzz.sh
|
||||
#
|
||||
# The script relies on the OSS-Fuzz base-builder environment, in particular
|
||||
# the compile_native_go_fuzzer_v2 helper that turns native Go fuzz targets
|
||||
# (`func FuzzXxx(f *testing.F)`) into libFuzzer binaries placed in $OUT.
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")/.." # repository root
|
||||
|
||||
prepare() {
|
||||
go get github.com/AdamKorcz/go-118-fuzz-build/testing
|
||||
}
|
||||
|
||||
build_fuzzers() {
|
||||
compile_native_go_fuzzer_v2 tailscale.com/disco FuzzDiscoParse disco_parse_fuzzer
|
||||
compile_native_go_fuzzer_v2 tailscale.com/net/stun FuzzParseResponse stun_parser_response_fuzzer
|
||||
compile_native_go_fuzzer_v2 tailscale.com/net/stun FuzzParseBindingRequest stun_parser_request_fuzzer
|
||||
compile_native_go_fuzzer_v2 tailscale.com/net/dns/resolver FuzzClampEDNSSize dns_clamp_edns_size
|
||||
compile_native_go_fuzzer_v2 tailscale.com/net/traffic FuzzNodeHasherCompare traffic_node_hasher_compare
|
||||
compile_native_go_fuzzer_v2 tailscale.com/net/traffic FuzzSortNodes traffic_sort_nodes
|
||||
|
||||
compile_native_go_fuzzer_v2 tailscale.com/tailcfg FuzzNodeIsRouter tailcfg_node_isrouter
|
||||
|
||||
compile_native_go_fuzzer_v2 tailscale.com/types/geo FuzzPointSphericalAngleTo geo_spherical_angle_to
|
||||
|
||||
compile_native_go_fuzzer_v2 tailscale.com/util/cobs FuzzRoundtrip cobs_roundtrip
|
||||
compile_native_go_fuzzer_v2 tailscale.com/util/cobs FuzzMostlyBijective cobs_mostly_bijective
|
||||
compile_native_go_fuzzer_v2 tailscale.com/util/def FuzzBool def_bool
|
||||
compile_native_go_fuzzer_v2 tailscale.com/util/def FuzzDuration def_duration
|
||||
compile_native_go_fuzzer_v2 tailscale.com/util/nocasemaps FuzzAppendToLower nocase_append_tolower
|
||||
compile_native_go_fuzzer_v2 tailscale.com/util/safediff FuzzDiff safediff_diff
|
||||
|
||||
compile_native_go_fuzzer_v2 tailscale.com/wgengine/netlog FuzzQuotedLen netlog_quoted_len
|
||||
}
|
||||
|
||||
prepare
|
||||
build_fuzzers
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package stun
|
||||
|
||||
import "testing"
|
||||
|
||||
var minimalValidSTUN = []byte{
|
||||
0x00, 0x01, // message type: Binding request/response (STUN method + class)
|
||||
0x21, 0x12, 0xa4, 0x42, // fixed STUN magic cookie
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // transaction ID (8 bytes)
|
||||
}
|
||||
|
||||
func FuzzParseResponse(f *testing.F) {
|
||||
f.Add(minimalValidSTUN)
|
||||
// seeds from test cases
|
||||
f.Add([]byte{0x1, 0x1, 0x0, 0x14, 0x21, 0x12, 0xa4, 0x42, 0xeb, 0xc2, 0xd3,
|
||||
0x6e, 0xf4, 0x71, 0x21, 0x7c, 0x4f, 0x3e, 0x30, 0x8e, 0x80, 0x22, 0x0, 0x3, 0x61,
|
||||
0x62, 0x63, 0x0, 0x0, 0x20, 0x0, 0x8, 0x0, 0x1, 0xce, 0x66, 0x5e, 0x12, 0xa4,
|
||||
0x43})
|
||||
f.Add([]byte{0x1, 0x1, 0x0, 0xc, 0x21, 0x12, 0xa4, 0x42, 0x23, 0x60, 0xb1, 0x1e,
|
||||
0x3e, 0xc6, 0x8f, 0xfa, 0x93, 0xe0, 0x80, 0x7, 0x0, 0x20, 0x0, 0x8, 0x0, 0x1,
|
||||
0xc7, 0x86, 0x69, 0x57, 0x85, 0x6f})
|
||||
f.Add([]byte{0x1, 0x1, 0x0, 0x24, 0x21, 0x12, 0xa4, 0x42, 0x7e, 0x57, 0x96,
|
||||
0x68, 0x29, 0xf4, 0x44, 0x60, 0x9d, 0x1d, 0xea, 0xa6, 0x0, 0x1, 0x0, 0x8, 0x0,
|
||||
0x1, 0xe9, 0xd3, 0x48, 0x45, 0x21, 0x2d, 0x0, 0x4, 0x0, 0x8, 0x0, 0x1, 0xd, 0x96,
|
||||
0x4d, 0x48, 0xa9, 0xd4, 0x0, 0x5, 0x0, 0x8, 0x0, 0x1, 0xd, 0x97, 0x4d, 0x48,
|
||||
0xa9, 0xd5})
|
||||
f.Add([]byte{0x1, 0x1, 0x0, 0x24, 0x21, 0x12, 0xa4, 0x42, 0xeb, 0xc2, 0xd3,
|
||||
0x6e, 0xf4, 0x71, 0x21, 0x7c, 0x4f, 0x3e, 0x30, 0x8e, 0x80, 0x22, 0x0, 0xa, 0x65,
|
||||
0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x0, 0x0, 0x0, 0x20, 0x0,
|
||||
0x8, 0x0, 0x1, 0xce, 0x66, 0x5e, 0x12, 0xa4, 0x43, 0x80, 0x28, 0x0, 0x4, 0xb6,
|
||||
0x99, 0xbb, 0x2, 0x1, 0x1, 0x0, 0x24, 0x21, 0x12, 0xa4, 0x42})
|
||||
f.Add([]byte{0x1, 0x1, 0x0, 0x44, 0x21, 0x12, 0xa4, 0x42, 0x48, 0x2e, 0xb6,
|
||||
0x47, 0x15, 0xe8, 0xb2, 0x8e, 0xae, 0xad, 0x64, 0x44, 0x0, 0x1, 0x0, 0x8, 0x0,
|
||||
0x1, 0xe4, 0xab, 0x48, 0x45, 0x21, 0x2d, 0x0, 0x4, 0x0, 0x8, 0x0, 0x1, 0x27,
|
||||
0x10, 0xd9, 0xa, 0x44, 0x98, 0x0, 0x5, 0x0, 0x8, 0x0, 0x1, 0x27, 0x11, 0xd9,
|
||||
0x74, 0x7a, 0x8a, 0x80, 0x20, 0x0, 0x8, 0x0, 0x1, 0xc5, 0xb9, 0x69, 0x57, 0x85,
|
||||
0x6f, 0x80, 0x22, 0x0, 0x10, 0x56, 0x6f, 0x76, 0x69, 0x64, 0x61, 0x2e, 0x6f,
|
||||
0x72, 0x67, 0x20, 0x30, 0x2e, 0x39, 0x36, 0x0})
|
||||
f.Add([]byte{0x1, 0x1, 0x0, 0x48, 0x21, 0x12, 0xa4, 0x42, 0x6, 0xf5, 0x66, 0x85,
|
||||
0xd2, 0x8a, 0xf3, 0xe6, 0x9c, 0xe3, 0x41, 0xe2, 0x0, 0x1, 0x0, 0x14, 0x0, 0x2,
|
||||
0x90, 0xce, 0x26, 0x2, 0x0, 0xd1, 0xb4, 0xcf, 0xc1, 0x0, 0x38, 0xb2, 0x31, 0xff,
|
||||
0xfe, 0xef, 0x96, 0xf6, 0x80, 0x2b, 0x0, 0x14, 0x0, 0x2, 0xd, 0x96, 0x26, 0x4,
|
||||
0xa8, 0x80, 0x0, 0x2, 0x0, 0xd1, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc5, 0x70, 0x1, 0x0,
|
||||
0x20, 0x0, 0x14, 0x0, 0x2, 0xb1, 0xdc, 0x7, 0x10, 0xa4, 0x93, 0xb2, 0x3a, 0xa7,
|
||||
0x85, 0xea, 0x38, 0xc2, 0x19, 0x62, 0xc, 0xd7, 0x14})
|
||||
f.Add([]byte{0x1, 0x1, 0x0, 0xc, 0x21, 0x12, 0xa4, 0x42, 0xf9, 0xf1, 0x21, 0xcb,
|
||||
0xde, 0x7d, 0x7c, 0x75, 0x92, 0x3c, 0xe2, 0x71, 0x0, 0x20, 0x0, 0x8, 0x0, 0x1,
|
||||
0xc7, 0x87, 0x69, 0x57, 0x85, 0x6f})
|
||||
f.Add([]byte{0x1, 0x1, 0x0, 0x18, 0x21, 0x12, 0xa4, 0x42, 0x4f, 0xd5, 0xd2, 0x2,
|
||||
0xdc, 0xb3, 0x7d, 0x31, 0xfc, 0x77, 0x33, 0x6, 0x0, 0x20, 0x0, 0x14, 0x0, 0x2,
|
||||
0xcd, 0x3d, 0x21, 0x12, 0xa4, 0x42, 0x4f, 0xd5, 0xd2, 0x2, 0xdc, 0xb3, 0x82,
|
||||
0xce, 0x2d, 0xc3, 0xfc, 0xc7})
|
||||
f.Add([]byte{0x1, 0x1, 0x0, 0x14, 0x21, 0x12, 0xa4, 0x42, 0xeb, 0xc2, 0xd3,
|
||||
0x6e, 0xf4, 0x71, 0x21, 0x7c, 0x4f, 0x3e, 0x30, 0x8e, 0x80, 0x22, 0x0, 0x1, 0x61,
|
||||
0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x8, 0x0, 0x1, 0xce, 0x66, 0x5e, 0x12, 0xa4, 0x43})
|
||||
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
_, _, _ = ParseResponse(data)
|
||||
})
|
||||
}
|
||||
|
||||
func FuzzParseBindingRequest(f *testing.F) {
|
||||
f.Add(minimalValidSTUN)
|
||||
f.Add(Request(NewTxID()))
|
||||
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
_, _ = ParseBindingRequest(data)
|
||||
})
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
//go:build gofuzz
|
||||
|
||||
package stun
|
||||
|
||||
func FuzzStunParser(data []byte) int {
|
||||
_, _, _ = ParseResponse(data)
|
||||
|
||||
_, _ = ParseBindingRequest(data)
|
||||
return 1
|
||||
}
|
||||
@@ -125,8 +125,8 @@ func FuzzNodeHasherCompare(f *testing.F) {
|
||||
selfID, aID, bID := seed[0], seed[1], seed[2]
|
||||
f.Add(selfID, aID, bID)
|
||||
}
|
||||
|
||||
f.Fuzz(func(t *testing.T, selfID, aID, bID uint64) {
|
||||
t.Logf("selfID %d, aID %d, bID %d", selfID, aID, bID)
|
||||
h := traffic.MakeRendezvousHasher(tailcfg.NodeID(selfID))
|
||||
a, b := tailcfg.NodeID(aID), tailcfg.NodeID(bID)
|
||||
c := h.Compare(a, b)
|
||||
@@ -153,8 +153,8 @@ func FuzzSortNodes(f *testing.F) {
|
||||
} {
|
||||
f.Add(seed[0], seed[1])
|
||||
}
|
||||
|
||||
f.Fuzz(func(t *testing.T, seed1, seed2 uint64) {
|
||||
t.Logf("using random seeds %d %d", seed1, seed2)
|
||||
rnd := rand.New(rand.NewPCG(seed1, seed2))
|
||||
|
||||
wantScore := traffic.Score(rnd.IntN(2000))
|
||||
|
||||
@@ -128,7 +128,7 @@ func TestAllocations(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func Fuzz(f *testing.F) {
|
||||
func FuzzBlock512(f *testing.F) {
|
||||
f.Fuzz(func(t *testing.T, seed int64) {
|
||||
c := qt.New(t)
|
||||
|
||||
|
||||
Reference in new issue
Block a user