fix overflow of the max_ack_delay when parsing transport parameters

This commit is contained in:
Marten Seemann 2020-08-19 12:07:58 +07:00
parent 2f736d3599
commit d476067f65
3 changed files with 8 additions and 8 deletions

View file

@ -71,7 +71,7 @@ const MaxAckDelayExponent = 20
const DefaultMaxAckDelay = 25 * time.Millisecond const DefaultMaxAckDelay = 25 * time.Millisecond
// MaxMaxAckDelay is the maximum max_ack_delay // MaxMaxAckDelay is the maximum max_ack_delay
const MaxMaxAckDelay = 1 << 14 * time.Millisecond const MaxMaxAckDelay = (1<<14 - 1) * time.Millisecond
// MaxConnIDLen is the maximum length of the connection ID // MaxConnIDLen is the maximum length of the connection ID
const MaxConnIDLen = 20 const MaxConnIDLen = 20

View file

@ -248,16 +248,16 @@ var _ = Describe("Transport Parameters", func() {
Expect(err.Error()).To(ContainSubstring("TRANSPORT_PARAMETER_ERROR: inconsistent transport parameter length")) Expect(err.Error()).To(ContainSubstring("TRANSPORT_PARAMETER_ERROR: inconsistent transport parameter length"))
}) })
It("handles max_ack_delays that decode to a negative duration", func() { It("handles huge max_ack_delay values", func() {
b := &bytes.Buffer{} b := &bytes.Buffer{}
val := uint64(math.MaxUint64) / 5 val := uint64(math.MaxUint64) / 5
utils.WriteVarInt(b, uint64(maxAckDelayParameterID)) utils.WriteVarInt(b, uint64(maxAckDelayParameterID))
utils.WriteVarInt(b, uint64(utils.VarIntLen(val))) utils.WriteVarInt(b, uint64(utils.VarIntLen(val)))
utils.WriteVarInt(b, val) utils.WriteVarInt(b, val)
addInitialSourceConnectionID(b) addInitialSourceConnectionID(b)
p := &TransportParameters{} err := (&TransportParameters{}).Unmarshal(b.Bytes(), protocol.PerspectiveClient)
Expect(p.Unmarshal(b.Bytes(), protocol.PerspectiveClient)).To(Succeed()) Expect(err).To(HaveOccurred())
Expect(p.MaxAckDelay).To(BeNumerically(">", 290*365*24*time.Hour)) Expect(err.Error()).To(ContainSubstring("invalid value for max_ack_delay"))
}) })
It("skips unknown parameters", func() { It("skips unknown parameters", func() {

View file

@ -297,10 +297,10 @@ func (p *TransportParameters) readNumericTransportParameter(
} }
p.AckDelayExponent = uint8(val) p.AckDelayExponent = uint8(val)
case maxAckDelayParameterID: case maxAckDelayParameterID:
maxAckDelay := time.Duration(val) * time.Millisecond if val > uint64(protocol.MaxMaxAckDelay/time.Millisecond) {
if maxAckDelay >= protocol.MaxMaxAckDelay { return fmt.Errorf("invalid value for max_ack_delay: %dms (maximum %dms)", val, protocol.MaxMaxAckDelay/time.Millisecond)
return fmt.Errorf("invalid value for max_ack_delay: %dms (maximum %dms)", maxAckDelay/time.Millisecond, (protocol.MaxMaxAckDelay-time.Millisecond)/time.Millisecond)
} }
maxAckDelay := time.Duration(val) * time.Millisecond
if maxAckDelay < 0 { if maxAckDelay < 0 {
maxAckDelay = utils.InfDuration maxAckDelay = utils.InfDuration
} }