diff --git a/fuzzing/transportparameters/fuzz.go b/fuzzing/transportparameters/fuzz.go index a3ca143d3ee..d0dd975fdcc 100644 --- a/fuzzing/transportparameters/fuzz.go +++ b/fuzzing/transportparameters/fuzz.go @@ -2,6 +2,7 @@ package transportparameters import ( "bytes" + "errors" "fmt" "github.com/quic-go/quic-go/fuzzing/internal/helper" @@ -26,23 +27,29 @@ func Fuzz(data []byte) int { return fuzzTransportParameters(data[PrefixLen:], helper.NthBit(data[0], 1)) } -func fuzzTransportParameters(data []byte, isServer bool) int { - perspective := protocol.PerspectiveClient - if isServer { - perspective = protocol.PerspectiveServer +func fuzzTransportParameters(data []byte, sentByServer bool) int { + sentBy := protocol.PerspectiveClient + if sentByServer { + sentBy = protocol.PerspectiveServer } tp := &wire.TransportParameters{} - if err := tp.Unmarshal(data, perspective); err != nil { + if err := tp.Unmarshal(data, sentBy); err != nil { return 0 } _ = tp.String() + if err := validateTransportParameters(tp, sentBy); err != nil { + panic(err) + } tp2 := &wire.TransportParameters{} - if err := tp2.Unmarshal(tp.Marshal(perspective), perspective); err != nil { + if err := tp2.Unmarshal(tp.Marshal(sentBy), sentBy); err != nil { fmt.Printf("%#v\n", tp) panic(err) } + if err := validateTransportParameters(tp2, sentBy); err != nil { + panic(err) + } return 1 } @@ -58,3 +65,34 @@ func fuzzTransportParametersForSessionTicket(data []byte) int { } return 1 } + +func validateTransportParameters(tp *wire.TransportParameters, sentBy protocol.Perspective) error { + if sentBy == protocol.PerspectiveClient && tp.StatelessResetToken != nil { + return errors.New("client's transport parameters contained stateless reset token") + } + if tp.MaxIdleTimeout < 0 { + return fmt.Errorf("negative max_idle_timeout: %s", tp.MaxIdleTimeout) + } + if tp.AckDelayExponent > 20 { + return fmt.Errorf("invalid ack_delay_exponent: %d", tp.AckDelayExponent) + } + if tp.MaxUDPPayloadSize < 1200 { + return fmt.Errorf("invalid max_udp_payload_size: %d", tp.MaxUDPPayloadSize) + } + if tp.ActiveConnectionIDLimit < 2 { + return fmt.Errorf("invalid active_connection_id_limit: %d", tp.ActiveConnectionIDLimit) + } + if tp.OriginalDestinationConnectionID.Len() > 20 { + return fmt.Errorf("invalid original_destination_connection_id length: %s", tp.InitialSourceConnectionID) + } + if tp.InitialSourceConnectionID.Len() > 20 { + return fmt.Errorf("invalid initial_source_connection_id length: %s", tp.InitialSourceConnectionID) + } + if tp.RetrySourceConnectionID != nil && tp.RetrySourceConnectionID.Len() > 20 { + return fmt.Errorf("invalid retry_source_connection_id length: %s", tp.RetrySourceConnectionID) + } + if tp.PreferredAddress != nil && tp.PreferredAddress.ConnectionID.Len() > 20 { + return fmt.Errorf("invalid preferred_address connection ID length: %s", tp.PreferredAddress.ConnectionID) + } + return nil +}