Files
tailscale/net/stun/fuzz_test.go
Mike Jensen bb94defdd0 fuzz: improve fuzz testing and seed corups (#21340)
This change improves the initial fuzz seeds to get better coverage. It also includes a fix to the geo fuzzing to avoid a harness induced failure when a NaN input is provided.

No actual code logic changes, test only.

Updates tailscale/corp#46608

Change-Id: I0985b6d3a75603927451eea0a25f4cd72c039795

Signed-off-by: Mike Jensen <mikej@tailscale.com>
2026-09-21 09:23:51 -06:00

113 lines
5.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package stun
import "testing"
// A STUN message is 20 bytes: 2-byte type, 2-byte length, 4-byte magic
// cookie at offsets 4–7, then a 12-byte transaction ID.
var minimalValidSTUN = []byte{
0x00, 0x01, // message type: Binding request (STUN method + class)
0x00, 0x00, // message length: 0
0x21, 0x12, 0xa4, 0x42, // fixed STUN magic cookie
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // transaction ID (12 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)
})
}
func FuzzMappedAddress(f *testing.F) {
f.Add([]byte{0x0, 0x1, 0xe4, 0xab, 0x48, 0x45, 0x21, 0x2d})
f.Add([]byte{0x0, 0x1, 0x21, 0x12, 0xa4, 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0})
f.Add([]byte{0x0, 0x1, 0xe9, 0xd3, 0x48, 0x45, 0x21, 0x2d})
f.Add([]byte{0x0, 0x2, 0x90, 0xce, 0x26, 0x2, 0x0, 0xd1, 0xb4, 0xcf, 0xc1, 0x0,
0x38, 0xb2, 0x31, 0xff, 0xfe, 0xef, 0x96, 0xf6})
f.Fuzz(func(t *testing.T, data []byte) {
_, _, _ = mappedAddress(data)
})
}
func FuzzForeachAttr(f *testing.F) {
// Single MAPPED-ADDRESS attribute (IPv4): type 0x0001
f.Add([]byte{0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0xe9, 0xd3,
0x48, 0x45, 0x21, 0x2d})
// Single MAPPED-ADDRESS attribute (IPv6): type 0x0001
f.Add([]byte{0x00, 0x01, 0x00, 0x14, 0x00, 0x02, 0x90, 0xce, 0x26, 0x02, 0x00, 0xd1, 0xb4, 0xcf, 0xc1, 0x00, 0x38, 0xb2,
0x31, 0xff, 0xfe, 0xef, 0x96, 0xf6})
f.Fuzz(func(t *testing.T, data []byte) {
_ = foreachAttr(data, func(_ uint16, _ []byte) error {
return nil
})
})
}
func FuzzXorMappedAddress(f *testing.F) {
f.Add([]byte{0x00, 0x01, 0xe4, 0xab, 0x48, 0x45, 0x21, 0x2d})
f.Add([]byte{0x02, 0x90, 0xce, 0x26, 0x1, 0x0, 0xd1, 0xb4, 0xcf, 0xc1, 0x38, 0xb2})
f.Fuzz(func(t *testing.T, data []byte) {
var tx TxID
_, _, _ = xorMappedAddress(tx, data)
})
}