From 2593b1af81ad2f1e164325f5923371a878bc3116 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 8 Aug 2020 15:34:56 +0700 Subject: [PATCH] add fuzzing for transport parameters --- fuzzing/transportparameters/cmd/corpus.go | 92 ++++++++++++++++++++++ fuzzing/transportparameters/corpus/tp0 | Bin 0 -> 180 bytes fuzzing/transportparameters/corpus/tp1 | Bin 0 -> 217 bytes fuzzing/transportparameters/corpus/tp10 | Bin 0 -> 69 bytes fuzzing/transportparameters/corpus/tp11 | Bin 0 -> 82 bytes fuzzing/transportparameters/corpus/tp12 | Bin 0 -> 152 bytes fuzzing/transportparameters/corpus/tp13 | Bin 0 -> 98 bytes fuzzing/transportparameters/corpus/tp14 | Bin 0 -> 54 bytes fuzzing/transportparameters/corpus/tp15 | Bin 0 -> 93 bytes fuzzing/transportparameters/corpus/tp16 | Bin 0 -> 127 bytes fuzzing/transportparameters/corpus/tp17 | Bin 0 -> 78 bytes fuzzing/transportparameters/corpus/tp18 | Bin 0 -> 73 bytes fuzzing/transportparameters/corpus/tp19 | Bin 0 -> 94 bytes fuzzing/transportparameters/corpus/tp2 | Bin 0 -> 77 bytes fuzzing/transportparameters/corpus/tp3 | Bin 0 -> 204 bytes fuzzing/transportparameters/corpus/tp4 | Bin 0 -> 82 bytes fuzzing/transportparameters/corpus/tp5 | Bin 0 -> 136 bytes fuzzing/transportparameters/corpus/tp6 | Bin 0 -> 76 bytes fuzzing/transportparameters/corpus/tp7 | Bin 0 -> 82 bytes fuzzing/transportparameters/corpus/tp8 | Bin 0 -> 111 bytes fuzzing/transportparameters/corpus/tp9 | Bin 0 -> 174 bytes fuzzing/transportparameters/fuzz.go | 56 +++++++++++++ internal/wire/transport_parameters.go | 8 +- 23 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 fuzzing/transportparameters/cmd/corpus.go create mode 100644 fuzzing/transportparameters/corpus/tp0 create mode 100644 fuzzing/transportparameters/corpus/tp1 create mode 100644 fuzzing/transportparameters/corpus/tp10 create mode 100644 fuzzing/transportparameters/corpus/tp11 create mode 100644 fuzzing/transportparameters/corpus/tp12 create mode 100644 fuzzing/transportparameters/corpus/tp13 create mode 100644 fuzzing/transportparameters/corpus/tp14 create mode 100644 fuzzing/transportparameters/corpus/tp15 create mode 100644 fuzzing/transportparameters/corpus/tp16 create mode 100644 fuzzing/transportparameters/corpus/tp17 create mode 100644 fuzzing/transportparameters/corpus/tp18 create mode 100644 fuzzing/transportparameters/corpus/tp19 create mode 100644 fuzzing/transportparameters/corpus/tp2 create mode 100644 fuzzing/transportparameters/corpus/tp3 create mode 100644 fuzzing/transportparameters/corpus/tp4 create mode 100644 fuzzing/transportparameters/corpus/tp5 create mode 100644 fuzzing/transportparameters/corpus/tp6 create mode 100644 fuzzing/transportparameters/corpus/tp7 create mode 100644 fuzzing/transportparameters/corpus/tp8 create mode 100644 fuzzing/transportparameters/corpus/tp9 create mode 100644 fuzzing/transportparameters/fuzz.go 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 0000000000000000000000000000000000000000..d3c244484ee2e42b3fe48e669f3fc2fdb020d666 GIT binary patch literal 180 zcmV;l089U%)JDV#71lg}4Xu5oNfreJx_rD}1_=7>4NE_b@`MKg4+I3cnHtdu2ZAf~eXwA0)0RRI6MXU=5zyJgM{7Y(u3IP)U6bZYbMIlv@a|Y7{M<93} zwa}Os1PwRn=)SMF8>CgdG$eXK0kLB3*#lURt3VwNdxLc=9^1Nwz4LM0HmJ{PJo{ce iDR-X?g}wx1O&$&b1`hxb4ydm2sIuq*-SEIH2g5Wek4DJ= literal 0 HcmV?d00001 diff --git a/fuzzing/transportparameters/corpus/tp1 b/fuzzing/transportparameters/corpus/tp1 new file mode 100644 index 0000000000000000000000000000000000000000..be6b122fa3f369984fb152fb322ad2fd081fe9f6 GIT binary patch literal 217 zcmV;~04D!FnnBGC?tMc7Y5%gQN206D#{~%Ql^@ldJsFk;0$LRZ1f~_U$^-&`9S8vn z2?VBY-jq?G+#((E4_oe*$&j>xeP4YLCm4ZlcOu0=-1J3xke@g5ANc8|?83v* TZb$$L_wzI@9oR%;vJ}uH&RJfG literal 0 HcmV?d00001 diff --git a/fuzzing/transportparameters/corpus/tp10 b/fuzzing/transportparameters/corpus/tp10 new file mode 100644 index 0000000000000000000000000000000000000000..9a8d202b9bcd64fb06f9d412522995d11cc31fcd GIT binary patch literal 69 zcmV-L0J{IhtVpy1Qb+{|`(fAPqytxT1_;#k*US755&s7Si`3`}1O$<2S~Lg(V&NL zH7&jx009920|G^?3jqKM0SycQ4gy&L4;#W$!z9kPi%T>*x*OTDTDF=%(7MvH_t!*B E_$Blrp#T5? literal 0 HcmV?d00001 diff --git a/fuzzing/transportparameters/corpus/tp14 b/fuzzing/transportparameters/corpus/tp14 new file mode 100644 index 0000000000000000000000000000000000000000..a9693444bc27ef0d90e309aaf53a2c942c7f9e8b GIT binary patch literal 54 zcmZoV<($CS#>!Oh!N$nV&eGhtubqXd?j;9PfiNedJR>6mGn4BYZbk+!CWlTQ20oT< J9gD^M3;<=23uXWS literal 0 HcmV?d00001 diff --git a/fuzzing/transportparameters/corpus/tp15 b/fuzzing/transportparameters/corpus/tp15 new file mode 100644 index 0000000000000000000000000000000000000000..e4da18fc49e1e4a94d4dbd61b9a03b107006ed3f GIT binary patch literal 93 zcmV-j0HXh1I6>?WnbCB56Ux(k)5Rm3H?Wfh1fA6A%?1HI2LUJq0U8JbbhZfunv#!N z0RlqC0|G^?3jqKM0SN*Sm8n$F)RVEWkR*PbCfIwO00sf03A~`g4g{`w)&36vWcVU& literal 0 HcmV?d00001 diff --git a/fuzzing/transportparameters/corpus/tp16 b/fuzzing/transportparameters/corpus/tp16 new file mode 100644 index 0000000000000000000000000000000000000000..164fa983816c60f00f53447123afd62c0a466a01 GIT binary patch literal 127 zcmV-_0D%9tyg?HTvEXt&+4vcAeB~xo1qi^4!`X^c2WbWf)b^sho6Xf42LU|<1c?Jd z-3SQbM$eL$0X<3y1iL3<`~e8S00DQKLw!^O0!6F~0zwxG0RRjD4gnz#B_}gnuDvQW hM*7BBB`~vM3-PKi0@;9$lgeB?{{$rLRGeXe^n62sFev~4 literal 0 HcmV?d00001 diff --git a/fuzzing/transportparameters/corpus/tp17 b/fuzzing/transportparameters/corpus/tp17 new file mode 100644 index 0000000000000000000000000000000000000000..8a9a11649cbbe8905e69222796de5e85d4bbbaf9 GIT binary patch literal 78 zcmY$q=VHlp)RvW{-91c;jVbCpJ4=g5c{U4^M+*m|04Gbs(lZf^90wSfyz+`S)H5@= huHgpq7!%F1y3@Fr947KG@NqnU{Y&%8mUEBz830sj7wZ53 literal 0 HcmV?d00001 diff --git a/fuzzing/transportparameters/corpus/tp18 b/fuzzing/transportparameters/corpus/tp18 new file mode 100644 index 0000000000000000000000000000000000000000..ec202f0a3ad769da21512251511c09686a023eb7 GIT binary patch literal 73 zcmV-P0Ji`9Wk(?ksaZH#PCF?#JXv)G1f{s??FIoA2Lfve1OiHE2n3n?*yjlZy_oOp%~2LT=g2;?RdPZ(Hj_Xq(W2>}=Z z0zmKs0!6F~0RRdDK++5V4g`=@YB~=YGVKf;bPx# literal 0 HcmV?d00001 diff --git a/fuzzing/transportparameters/corpus/tp2 b/fuzzing/transportparameters/corpus/tp2 new file mode 100644 index 0000000000000000000000000000000000000000..0966dc257c58820f6b0d47a2e4b5d88b6c362897 GIT binary patch literal 77 zcmV-T0J8tiFH71ATvn&W8%3WVZDIuiO|1q9>hGER$rF`K2LfBj1PI2G4vFaaG6e_% jW#b6~Wqkn%zyJaEdD6J`0|G^?3jqKM0UHhibh{4#k9!*& literal 0 HcmV?d00001 diff --git a/fuzzing/transportparameters/corpus/tp3 b/fuzzing/transportparameters/corpus/tp3 new file mode 100644 index 0000000000000000000000000000000000000000..d93ffcefc822903765943a85046094bc2c2ccf93 GIT binary patch literal 204 zcmV;-05ktm(?^{SlK*lWsm4mb@#^?eG@k_l7zP4sMh66n8gdE*0$C>r2=d)qvI5&L zI|&4sz~v_a0z$6Yrg zkEny-_Bw(A#rYn1^PFfjZ7OI!@eMeitd~l4y6{{AGFD^0gD!uLecoq_$jmqoIf>mW z-r%FmPXfIsa*}XX&d0%fkV!n?S5o=A;5o()2=qmzW-IGgY7Yx4a775Ygygvw$P^F* GvWf_ZwpWh; literal 0 HcmV?d00001 diff --git a/fuzzing/transportparameters/corpus/tp4 b/fuzzing/transportparameters/corpus/tp4 new file mode 100644 index 0000000000000000000000000000000000000000..6802692adbdf957a4eaa05bdaa7768056276a4a9 GIT binary patch literal 82 zcmV-Y0ImP5Za|j{f$wV~1;Ko~^R1u-0)7Mr0#Qr{0XhT%L_Y`wl(PlU2?V@!yK0|G^?3jqKM0SyiUaNG|KfF-7}_P%T@S($YVZdTG73;+NC literal 0 HcmV?d00001 diff --git a/fuzzing/transportparameters/corpus/tp5 b/fuzzing/transportparameters/corpus/tp5 new file mode 100644 index 0000000000000000000000000000000000000000..1091419e802ed26140f4375787bfb9ff5de4d6a6 GIT binary patch literal 136 zcmV;30C)e08%rPr)ZdEk1qk^mp(hTF>$L_1o!NDs2LTxb0z_E|1fsNf&It(m;FGLW zr^c-T2*3aX0GE|jP6Gl(tP27}7zzSFY777X01g2f4<=55hiXb0&%1xhn@8IaT?D_x qe(0Y_n$QNdj{wiG{$7pIm}wds5D~nsf#|^QitWse)|ttD)Zfj88aUkm literal 0 HcmV?d00001 diff --git a/fuzzing/transportparameters/corpus/tp6 b/fuzzing/transportparameters/corpus/tp6 new file mode 100644 index 0000000000000000000000000000000000000000..1b087fb9c3d185cd76afb0e83aef58149c879fce GIT binary patch literal 76 zcmV-S0JHyD97NOu=@C~22-zCwEpsCYYX$_i4<@Sz2;#ii-T2=P<7LGPd(Y!3hs83$CsFmgB^s0W!Q R2CJ>*sTaqYG=h(4L--w4@W`KeSTjowLlf)zi`yW zy=&3&*4-5Yk~g0jRy#Ukn5v=pWUcn;SfPoXxNw4R91R9oj#w4RkueVn4g|5O{<9Am caNQH9F$BPZMOxTl9_*dElL00ElFtOoN$Gz?IsgCw literal 0 HcmV?d00001 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()))