diff --git a/fuzzing/transportparameters/cmd/corpus.go b/fuzzing/transportparameters/cmd/corpus.go new file mode 100644 index 00000000..c9105aef --- /dev/null +++ b/fuzzing/transportparameters/cmd/corpus.go @@ -0,0 +1,92 @@ +package main + +import ( + "fmt" + "log" + "math" + "math/rand" + "net" + "os" + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" + + "github.com/lucas-clemente/quic-go/internal/wire" +) + +func getRandomData(l int) []byte { + b := make([]byte, l) + rand.Read(b) + return b +} + +func getRandomValue() uint64 { + maxVals := []int64{math.MaxUint8 / 4, math.MaxUint16 / 4, math.MaxUint32 / 4, math.MaxUint64 / 4} + return uint64(rand.Int63n(maxVals[int(rand.Int31n(4))])) +} + +func main() { + rand.Seed(1337) + for i := 0; i < 20; i++ { + tp := &wire.TransportParameters{ + InitialMaxStreamDataBidiLocal: protocol.ByteCount(getRandomValue()), + InitialMaxStreamDataBidiRemote: protocol.ByteCount(getRandomValue()), + InitialMaxStreamDataUni: protocol.ByteCount(getRandomValue()), + InitialMaxData: protocol.ByteCount(getRandomValue()), + MaxAckDelay: time.Duration(getRandomValue()), + AckDelayExponent: uint8(getRandomValue()), + DisableActiveMigration: getRandomValue()%2 == 0, + MaxUDPPayloadSize: protocol.ByteCount(getRandomValue()), + MaxUniStreamNum: protocol.StreamNum(getRandomValue()), + MaxBidiStreamNum: protocol.StreamNum(getRandomValue()), + MaxIdleTimeout: time.Duration(getRandomValue()), + ActiveConnectionIDLimit: getRandomValue(), + } + if rand.Int()%2 == 0 { + tp.OriginalDestinationConnectionID = protocol.ConnectionID(getRandomData(rand.Intn(50))) + } + if rand.Int()%2 == 0 { + tp.InitialSourceConnectionID = protocol.ConnectionID(getRandomData(rand.Intn(50))) + } + if rand.Int()%2 == 0 { + connID := protocol.ConnectionID(getRandomData(rand.Intn(50))) + tp.RetrySourceConnectionID = &connID + } + if rand.Int()%2 == 0 { + var token protocol.StatelessResetToken + rand.Read(token[:]) + tp.StatelessResetToken = &token + } + if rand.Int()%2 == 0 { + var token protocol.StatelessResetToken + rand.Read(token[:]) + tp.PreferredAddress = &wire.PreferredAddress{ + IPv4: net.IPv4(uint8(rand.Int()), uint8(rand.Int()), uint8(rand.Int()), uint8(rand.Int())), + IPv4Port: uint16(rand.Int()), + IPv6: net.IP(getRandomData(16)), + IPv6Port: uint16(rand.Int()), + ConnectionID: protocol.ConnectionID(getRandomData(rand.Intn(25))), + StatelessResetToken: token, + } + } + pers := protocol.PerspectiveServer + if rand.Int()%2 == 0 { + pers = protocol.PerspectiveClient + } + if err := writeCorpusFile(fmt.Sprintf("tp%d", i), tp.Marshal(pers)); err != nil { + log.Fatal(err) + } + } +} + +func writeCorpusFile(name string, data []byte) error { + file, err := os.Create("corpus/" + name) + if err != nil { + return err + } + data = append(getRandomData(2), data...) + if _, err := file.Write(data); err != nil { + return err + } + return file.Close() +} diff --git a/fuzzing/transportparameters/corpus/tp0 b/fuzzing/transportparameters/corpus/tp0 new file mode 100644 index 00000000..d3c24448 Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp0 differ diff --git a/fuzzing/transportparameters/corpus/tp1 b/fuzzing/transportparameters/corpus/tp1 new file mode 100644 index 00000000..be6b122f Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp1 differ diff --git a/fuzzing/transportparameters/corpus/tp10 b/fuzzing/transportparameters/corpus/tp10 new file mode 100644 index 00000000..9a8d202b Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp10 differ diff --git a/fuzzing/transportparameters/corpus/tp11 b/fuzzing/transportparameters/corpus/tp11 new file mode 100644 index 00000000..561deb59 Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp11 differ diff --git a/fuzzing/transportparameters/corpus/tp12 b/fuzzing/transportparameters/corpus/tp12 new file mode 100644 index 00000000..3d4ccd4d Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp12 differ diff --git a/fuzzing/transportparameters/corpus/tp13 b/fuzzing/transportparameters/corpus/tp13 new file mode 100644 index 00000000..c43110c3 Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp13 differ diff --git a/fuzzing/transportparameters/corpus/tp14 b/fuzzing/transportparameters/corpus/tp14 new file mode 100644 index 00000000..a9693444 Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp14 differ diff --git a/fuzzing/transportparameters/corpus/tp15 b/fuzzing/transportparameters/corpus/tp15 new file mode 100644 index 00000000..e4da18fc Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp15 differ diff --git a/fuzzing/transportparameters/corpus/tp16 b/fuzzing/transportparameters/corpus/tp16 new file mode 100644 index 00000000..164fa983 Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp16 differ diff --git a/fuzzing/transportparameters/corpus/tp17 b/fuzzing/transportparameters/corpus/tp17 new file mode 100644 index 00000000..8a9a1164 Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp17 differ diff --git a/fuzzing/transportparameters/corpus/tp18 b/fuzzing/transportparameters/corpus/tp18 new file mode 100644 index 00000000..ec202f0a Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp18 differ diff --git a/fuzzing/transportparameters/corpus/tp19 b/fuzzing/transportparameters/corpus/tp19 new file mode 100644 index 00000000..6557eac3 Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp19 differ diff --git a/fuzzing/transportparameters/corpus/tp2 b/fuzzing/transportparameters/corpus/tp2 new file mode 100644 index 00000000..0966dc25 Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp2 differ diff --git a/fuzzing/transportparameters/corpus/tp3 b/fuzzing/transportparameters/corpus/tp3 new file mode 100644 index 00000000..d93ffcef Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp3 differ diff --git a/fuzzing/transportparameters/corpus/tp4 b/fuzzing/transportparameters/corpus/tp4 new file mode 100644 index 00000000..6802692a Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp4 differ diff --git a/fuzzing/transportparameters/corpus/tp5 b/fuzzing/transportparameters/corpus/tp5 new file mode 100644 index 00000000..1091419e Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp5 differ diff --git a/fuzzing/transportparameters/corpus/tp6 b/fuzzing/transportparameters/corpus/tp6 new file mode 100644 index 00000000..1b087fb9 Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp6 differ diff --git a/fuzzing/transportparameters/corpus/tp7 b/fuzzing/transportparameters/corpus/tp7 new file mode 100644 index 00000000..5e1e148e Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp7 differ diff --git a/fuzzing/transportparameters/corpus/tp8 b/fuzzing/transportparameters/corpus/tp8 new file mode 100644 index 00000000..209384b5 Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp8 differ diff --git a/fuzzing/transportparameters/corpus/tp9 b/fuzzing/transportparameters/corpus/tp9 new file mode 100644 index 00000000..8775295d Binary files /dev/null and b/fuzzing/transportparameters/corpus/tp9 differ diff --git a/fuzzing/transportparameters/fuzz.go b/fuzzing/transportparameters/fuzz.go new file mode 100644 index 00000000..18b20eea --- /dev/null +++ b/fuzzing/transportparameters/fuzz.go @@ -0,0 +1,56 @@ +package transportparameters + +import ( + "bytes" + "fmt" + + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +//go:generate go run ./cmd/corpus.go +func Fuzz(data []byte) int { + if len(data) <= 1 { + return 0 + } + + if data[0]%2 == 0 { + return fuzzTransportParametersForSessionTicket(data[1:]) + } + return fuzzTransportParameters(data[1:]) +} + +func fuzzTransportParameters(data []byte) int { + perspective := protocol.PerspectiveServer + if data[0]%2 == 1 { + perspective = protocol.PerspectiveServer + } + data = data[1:] + + tp := &wire.TransportParameters{} + if err := tp.Unmarshal(data, perspective); err != nil { + return 0 + } + _ = tp.String() + + tp2 := &wire.TransportParameters{} + if err := tp2.Unmarshal(tp.Marshal(perspective), perspective); err != nil { + fmt.Printf("%#v\n", tp) + panic(err) + } + return 1 +} + +func fuzzTransportParametersForSessionTicket(data []byte) int { + tp := &wire.TransportParameters{} + if err := tp.UnmarshalFromSessionTicket(bytes.NewReader(data)); err != nil { + return 0 + } + buf := &bytes.Buffer{} + tp.MarshalForSessionTicket(buf) + tp2 := &wire.TransportParameters{} + if err := tp2.UnmarshalFromSessionTicket(bytes.NewReader(buf.Bytes())); err != nil { + panic(err) + } + return 1 +} diff --git a/internal/wire/transport_parameters.go b/internal/wire/transport_parameters.go index 9eae574e..4694cc17 100644 --- a/internal/wire/transport_parameters.go +++ b/internal/wire/transport_parameters.go @@ -358,9 +358,11 @@ func (p *TransportParameters) Marshal(pers protocol.Perspective) []byte { } if pers == protocol.PerspectiveServer { // stateless_reset_token - utils.WriteVarInt(b, uint64(statelessResetTokenParameterID)) - utils.WriteVarInt(b, 16) - b.Write(p.StatelessResetToken[:]) + if p.StatelessResetToken != nil { + utils.WriteVarInt(b, uint64(statelessResetTokenParameterID)) + utils.WriteVarInt(b, 16) + b.Write(p.StatelessResetToken[:]) + } // original_destination_connection_id utils.WriteVarInt(b, uint64(originalDestinationConnectionIDParameterID)) utils.WriteVarInt(b, uint64(p.OriginalDestinationConnectionID.Len()))