Skip to content

Commit 05086a7

Browse files
committed
quic: fix panic when handling resent CRYPTO data
When pipe.discardBefore was called with an offset greater than the current pipe.end position, we would update pipe.start but not pipe.end, leaving the pipe in an inconsistent state where start > end. This could then subsequently cause a panic when writing data that lies before pipe.start. This sequence occurs when handling several in-order CRYPTO frames (where we skip writing in-order data to the pipe, but still call discardBefore), followed by an out-of-order frame containing resent data. Change-Id: Ibac0caad53cd30dac1cd4719a825226809872d96 Reviewed-on: https://go-review.googlesource.com/c/net/+/538775 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Jonathan Amsterdam <[email protected]>
1 parent 0526b49 commit 05086a7

File tree

3 files changed

+25
-0
lines changed

3 files changed

+25
-0
lines changed

internal/quic/crypto_stream_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,21 @@ func TestCryptoStreamReceive(t *testing.T) {
9494
end: 3000,
9595
want: 4000,
9696
}},
97+
}, {
98+
name: "resent consumed data",
99+
frames: []frame{{
100+
start: 0,
101+
end: 1000,
102+
want: 1000,
103+
}, {
104+
start: 1000,
105+
end: 2000,
106+
want: 2000,
107+
}, {
108+
start: 0,
109+
end: 1000,
110+
want: 2000,
111+
}},
97112
}} {
98113
t.Run(test.name, func(t *testing.T) {
99114
var s cryptoStream

internal/quic/pipe.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,5 @@ func (p *pipe) discardBefore(off int64) {
146146
p.tail = nil
147147
}
148148
p.start = off
149+
p.end = max(p.end, off)
149150
}

internal/quic/pipe_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ func TestPipeWrites(t *testing.T) {
6161
discardBeforeOp{10000},
6262
writeOp{10000, 20000},
6363
},
64+
}, {
65+
desc: "discard before writing",
66+
ops: []op{
67+
discardBeforeOp{1000},
68+
writeOp{0, 1},
69+
},
6470
}} {
6571
var p pipe
6672
var wantset rangeset[int64]
@@ -78,6 +84,9 @@ func TestPipeWrites(t *testing.T) {
7884
p.discardBefore(o.off)
7985
wantset.sub(0, o.off)
8086
wantStart = o.off
87+
if o.off > wantEnd {
88+
wantEnd = o.off
89+
}
8190
}
8291
if p.start != wantStart || p.end != wantEnd {
8392
t.Errorf("%v: after %#v p contains [%v,%v), want [%v,%v)", test.desc, test.ops[:i+1], p.start, p.end, wantStart, wantEnd)

0 commit comments

Comments
 (0)