Skip to content

Commit e0b83e0

Browse files
committed
BUGFIX: memory was allocated based on encoded length instead of the length of the io.Reader, causing potential DOS due to unexpected high memory usage (max MaxPacketLengthBytes)
Signed-off-by: Tim Ramlot <[email protected]>
1 parent 04301b4 commit e0b83e0

File tree

2 files changed

+13
-8
lines changed

2 files changed

+13
-8
lines changed

ber.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"io"
8+
"io/ioutil"
89
"math"
910
"os"
1011
"reflect"
@@ -352,13 +353,22 @@ func readPacket(reader io.Reader) (*Packet, int, error) {
352353
if MaxPacketLengthBytes > 0 && int64(length) > MaxPacketLengthBytes {
353354
return nil, read, fmt.Errorf("length %d greater than maximum %d", length, MaxPacketLengthBytes)
354355
}
355-
content := make([]byte, length)
356+
357+
var content []byte
356358
if length > 0 {
357-
_, err := io.ReadFull(reader, content)
359+
// Read the content and limit it to the parsed length.
360+
// If the content is less than the length, we return an EOF error.
361+
content, err = ioutil.ReadAll(io.LimitReader(reader, int64(length)))
362+
if err == nil && len(content) < int(length) {
363+
err = io.EOF
364+
}
358365
if err != nil {
359366
return nil, read, unexpectedEOF(err)
360367
}
361-
read += length
368+
read += len(content)
369+
} else {
370+
// If length == 0, we set the ByteValue to an empty slice
371+
content = make([]byte, 0)
362372
}
363373

364374
if p.ClassType == ClassUniversal {

fuzz_test.go

-5
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@ func FuzzDecodePacket(f *testing.F) {
3030
f.Add([]byte{0x09, 0x02, 0x85, 0x30})
3131
f.Add([]byte{0x09, 0x01, 0xcf})
3232

33-
// Set a limit on the length decoded in readPacket() since the call to
34-
// make([]byte, length) can allocate up to MaxPacketLengthBytes which is
35-
// currently 2 GB. This can cause memory related crashes when fuzzing in
36-
// parallel or on memory constrained devices.
37-
MaxPacketLengthBytes = 65536
3833
f.Fuzz(func(t *testing.T, data []byte) {
3934
stime := time.Now()
4035
p, err := DecodePacketErr(data)

0 commit comments

Comments
 (0)