Skip to content

Commit 36154a6

Browse files
committed
Add boundary check to fix #11
1 parent 43be865 commit 36154a6

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

nffile.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ func (nfFile *NfFile) AllRecords() (chan *FlowRecordV3, error) {
267267
recordChannel := make(chan *FlowRecordV3, 32)
268268
go func() {
269269
blockChannel, _ := nfFile.ReadDataBlocks()
270+
recordCnt := 0
270271
for dataBlock := range blockChannel {
271272
// fmt.Printf("Next block - type: %d, records: %d\n", dataBlock.Header.Type, dataBlock.Header.NumRecords)
272273
offset := 0
@@ -277,9 +278,12 @@ func (nfFile *NfFile) AllRecords() (chan *FlowRecordV3, error) {
277278
// fmt.Printf("Record %d type: %d, length: %d, numElementS: %d\n", i, recordType, recordSize, numElementS)
278279
switch recordType {
279280
case V3Record:
280-
if record := NewRecord(dataBlock.Data[offset : offset+int(recordSize)]); record != nil {
281+
if record, err := NewRecord(dataBlock.Data[offset : offset+int(recordSize)]); record != nil {
281282
record.GetSamplerInfo(nfFile)
282283
recordChannel <- record
284+
recordCnt++
285+
} else {
286+
fmt.Fprintf(os.Stderr, "Record %d: decoding error: %v\n", recordCnt, err)
283287
}
284288
case ExporterInfoRecordType:
285289
nfFile.addExporterInfo(dataBlock.Data[offset : offset+int(recordSize)])

record.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ package nfdump
1010

1111
import (
1212
"encoding/binary"
13+
"fmt"
1314
"net"
1415
"unsafe"
1516
)
@@ -45,15 +46,15 @@ type FlowRecordV3 struct {
4546
}
4647

4748
// Extract next flow record from []byte stream
48-
func NewRecord(record []byte) *FlowRecordV3 {
49+
func NewRecord(record []byte) (*FlowRecordV3, error) {
4950

5051
offset := 0
5152
recordType := binary.LittleEndian.Uint16(record[offset : offset+2])
5253
recordSize := binary.LittleEndian.Uint16(record[offset+2 : offset+4])
5354
numElements := binary.LittleEndian.Uint16(record[offset+4 : offset+6])
5455

5556
if recordType != V3Record {
56-
return nil
57+
return nil, fmt.Errorf("Not a v3 record")
5758
}
5859

5960
flowRecord := new(FlowRecordV3)
@@ -64,8 +65,15 @@ func NewRecord(record []byte) *FlowRecordV3 {
6465
flowRecord.recordHeader = (*recordHeaderV3)(unsafe.Pointer(&raw[0]))
6566
offset = 12
6667
for i := 0; i < int(numElements); i++ {
68+
// fmt.Printf(" . next Element at offset: %d\n", offset)
69+
if (offset + 4) > int(recordSize) {
70+
return nil, fmt.Errorf("Record header boundary check error")
71+
}
6772
elementType := binary.LittleEndian.Uint16(raw[offset : offset+2])
6873
elementSize := binary.LittleEndian.Uint16(raw[offset+2 : offset+4])
74+
if (offset + int(elementSize)) > int(recordSize) {
75+
return nil, fmt.Errorf("Record body boundary check error")
76+
}
6977
// fmt.Printf(" . Element type: %d, length: %d\n", elementType, elementSize)
7078
exOffset := offset + 4
7179
if elementType < MAXEXTENSIONS {
@@ -96,7 +104,7 @@ func NewRecord(record []byte) *FlowRecordV3 {
96104
flowRecord.packetInterval = 1
97105
flowRecord.spaceInterval = 0
98106

99-
return flowRecord
107+
return flowRecord, nil
100108
}
101109

102110
// Return generic extension

0 commit comments

Comments
 (0)