Skip to content

Commit 19ddaa0

Browse files
Sean-Derjupenur
andcommittedNov 9, 2023
Fix overflow in RFC8888
Use int instead of uint16. We assert that values on the wire can't be greater then math.MaxUint16, but when iterating we would overflow. This changes everything to int and adds tests Co-Authored-By: Juho Nurminen <juhonurm@gmail.com>
1 parent 934dd1a commit 19ddaa0

File tree

2 files changed

+39
-11
lines changed

2 files changed

+39
-11
lines changed
 

‎rfc8888.go

+12-11
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ func (b CCFeedbackReport) DestinationSSRC() []uint32 {
9393
}
9494

9595
// Len returns the length of the report in bytes
96-
func (b *CCFeedbackReport) Len() uint16 {
97-
n := uint16(0)
96+
func (b *CCFeedbackReport) Len() int {
97+
n := 0
9898
for _, block := range b.ReportBlocks {
9999
n += block.len()
100100
}
@@ -107,7 +107,7 @@ func (b *CCFeedbackReport) Header() Header {
107107
Padding: false,
108108
Count: FormatCCFB,
109109
Type: TypeTransportSpecificFeedback,
110-
Length: b.Len()/4 - 1,
110+
Length: uint16(b.Len()/4 - 1),
111111
}
112112
}
113113

@@ -122,7 +122,7 @@ func (b CCFeedbackReport) Marshal() ([]byte, error) {
122122
buf := make([]byte, length)
123123
copy(buf[:headerLength], headerBuf)
124124
binary.BigEndian.PutUint32(buf[headerLength:], b.SenderSSRC)
125-
offset := uint16(reportBlockOffset)
125+
offset := reportBlockOffset
126126
for _, block := range b.ReportBlocks {
127127
b, err := block.marshal()
128128
if err != nil {
@@ -164,10 +164,10 @@ func (b *CCFeedbackReport) Unmarshal(rawPacket []byte) error {
164164

165165
b.SenderSSRC = binary.BigEndian.Uint32(rawPacket[headerLength:])
166166

167-
reportTimestampOffset := uint16(len(rawPacket) - reportTimestampLength)
167+
reportTimestampOffset := len(rawPacket) - reportTimestampLength
168168
b.ReportTimestamp = binary.BigEndian.Uint32(rawPacket[reportTimestampOffset:])
169169

170-
offset := uint16(reportBlockOffset)
170+
offset := reportBlockOffset
171171
b.ReportBlocks = []CCFeedbackReportBlock{}
172172
for offset < reportTimestampOffset {
173173
var block CCFeedbackReportBlock
@@ -199,12 +199,12 @@ type CCFeedbackReportBlock struct {
199199
}
200200

201201
// len returns the length of the report block in bytes
202-
func (b *CCFeedbackReportBlock) len() uint16 {
202+
func (b *CCFeedbackReportBlock) len() int {
203203
n := len(b.MetricBlocks)
204204
if n%2 != 0 {
205205
n++
206206
}
207-
return reportsOffset + 2*uint16(n)
207+
return reportsOffset + 2*n
208208
}
209209

210210
func (b CCFeedbackReportBlock) String() string {
@@ -263,13 +263,14 @@ func (b *CCFeedbackReportBlock) unmarshal(rawPacket []byte) error {
263263
}
264264

265265
endSequence := b.BeginSequence + numReportsField
266-
numReports := endSequence - b.BeginSequence + 1
266+
numReports := int(endSequence - b.BeginSequence + 1)
267267

268-
if len(rawPacket) < reportsOffset+int(numReports)*2 {
268+
if len(rawPacket) < reportsOffset+numReports*2 {
269269
return errIncorrectNumReports
270270
}
271+
271272
b.MetricBlocks = make([]CCFeedbackMetricBlock, numReports)
272-
for i := uint16(0); i < numReports; i++ {
273+
for i := int(0); i < numReports; i++ {
273274
var mb CCFeedbackMetricBlock
274275
offset := reportsOffset + 2*i
275276
if err := mb.unmarshal(rawPacket[offset : offset+2]); err != nil {

‎rfc8888_test.go

+27
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package rtcp
55

66
import (
7+
"bytes"
78
"fmt"
89
"testing"
910

@@ -281,6 +282,16 @@ func TestCCFeedbackReportBlockUnmarshalMarshal(t *testing.T) {
281282
assert.Error(t, err)
282283
assert.ErrorIs(t, err, errIncorrectNumReports)
283284
})
285+
286+
t.Run("overflowNumReports", func(t *testing.T) {
287+
var block CCFeedbackReportBlock
288+
data := append([]byte{
289+
0, 0, 0, 0, // SSRC
290+
0, 0, 0x7F, 0xFB, // begin_seq, num_reports
291+
}, bytes.Repeat([]byte{0, 0}, 0x7FFF)...)
292+
err := block.unmarshal(data)
293+
assert.NoError(t, err)
294+
})
284295
}
285296

286297
func TestCCFeedbackReportUnmarshalMarshal(t *testing.T) {
@@ -396,3 +407,19 @@ func TestCCFeedbackReportUnmarshalMarshal(t *testing.T) {
396407
})
397408
}
398409
}
410+
411+
func TestCCFeedbackOverflow(t *testing.T) {
412+
p := &CCFeedbackReport{}
413+
err := p.Unmarshal(append([]byte{
414+
// Header
415+
0b10000000, // V = 2
416+
205, // h.Type = TypeTransportSpecificFeedback
417+
0, 0, // h.Length (unused)
418+
// SSRC
419+
0, 0, 0, 0,
420+
// CCFeedbackReportBlock
421+
0, 0, 0, 0, 0, 0,
422+
0x7F, 0xFB, // numReportsField
423+
}, bytes.Repeat([]byte{0, 0}, 0x7FFF)...))
424+
assert.ErrorIs(t, err, errReportBlockLength)
425+
}

0 commit comments

Comments
 (0)
Please sign in to comment.