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