github.com/quic-go/quic-go@v0.44.0/fuzzing/transportparameters/fuzz.go (about) 1 package transportparameters 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/quic-go/quic-go/fuzzing/internal/helper" 8 "github.com/quic-go/quic-go/internal/protocol" 9 "github.com/quic-go/quic-go/internal/wire" 10 ) 11 12 // PrefixLen is the number of bytes used for configuration 13 const PrefixLen = 1 14 15 // Fuzz fuzzes the QUIC transport parameters. 16 // 17 //go:generate go run ./cmd/corpus.go 18 func Fuzz(data []byte) int { 19 if len(data) <= PrefixLen { 20 return 0 21 } 22 23 if helper.NthBit(data[0], 0) { 24 return fuzzTransportParametersForSessionTicket(data[PrefixLen:]) 25 } 26 return fuzzTransportParameters(data[PrefixLen:], helper.NthBit(data[0], 1)) 27 } 28 29 func fuzzTransportParameters(data []byte, sentByServer bool) int { 30 sentBy := protocol.PerspectiveClient 31 if sentByServer { 32 sentBy = protocol.PerspectiveServer 33 } 34 35 tp := &wire.TransportParameters{} 36 if err := tp.Unmarshal(data, sentBy); err != nil { 37 return 0 38 } 39 _ = tp.String() 40 if err := validateTransportParameters(tp, sentBy); err != nil { 41 panic(err) 42 } 43 44 tp2 := &wire.TransportParameters{} 45 if err := tp2.Unmarshal(tp.Marshal(sentBy), sentBy); err != nil { 46 fmt.Printf("%#v\n", tp) 47 panic(err) 48 } 49 if err := validateTransportParameters(tp2, sentBy); err != nil { 50 panic(err) 51 } 52 return 1 53 } 54 55 func fuzzTransportParametersForSessionTicket(data []byte) int { 56 tp := &wire.TransportParameters{} 57 if err := tp.UnmarshalFromSessionTicket(data); err != nil { 58 return 0 59 } 60 b := tp.MarshalForSessionTicket(nil) 61 tp2 := &wire.TransportParameters{} 62 if err := tp2.UnmarshalFromSessionTicket(b); err != nil { 63 panic(err) 64 } 65 return 1 66 } 67 68 func validateTransportParameters(tp *wire.TransportParameters, sentBy protocol.Perspective) error { 69 if sentBy == protocol.PerspectiveClient && tp.StatelessResetToken != nil { 70 return errors.New("client's transport parameters contained stateless reset token") 71 } 72 if tp.MaxIdleTimeout < 0 { 73 return fmt.Errorf("negative max_idle_timeout: %s", tp.MaxIdleTimeout) 74 } 75 if tp.AckDelayExponent > 20 { 76 return fmt.Errorf("invalid ack_delay_exponent: %d", tp.AckDelayExponent) 77 } 78 if tp.MaxUDPPayloadSize < 1200 { 79 return fmt.Errorf("invalid max_udp_payload_size: %d", tp.MaxUDPPayloadSize) 80 } 81 if tp.ActiveConnectionIDLimit < 2 { 82 return fmt.Errorf("invalid active_connection_id_limit: %d", tp.ActiveConnectionIDLimit) 83 } 84 if tp.OriginalDestinationConnectionID.Len() > 20 { 85 return fmt.Errorf("invalid original_destination_connection_id length: %s", tp.InitialSourceConnectionID) 86 } 87 if tp.InitialSourceConnectionID.Len() > 20 { 88 return fmt.Errorf("invalid initial_source_connection_id length: %s", tp.InitialSourceConnectionID) 89 } 90 if tp.RetrySourceConnectionID != nil && tp.RetrySourceConnectionID.Len() > 20 { 91 return fmt.Errorf("invalid retry_source_connection_id length: %s", tp.RetrySourceConnectionID) 92 } 93 if tp.PreferredAddress != nil && tp.PreferredAddress.ConnectionID.Len() > 20 { 94 return fmt.Errorf("invalid preferred_address connection ID length: %s", tp.PreferredAddress.ConnectionID) 95 } 96 return nil 97 }