Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions polyamide/device/send.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ func (device *Device) RoutineReadFromTUN() {
}
tce := device.GetTCElement()
tce.Buffer = bufs[i]
tce.Packet = bufs[i][offset : offset+sizes[i]]
tcBufs = append(tcBufs, tce)

bufs[i] = device.GetMessageBuffer()
Expand Down
3 changes: 1 addition & 2 deletions polyamide/device/traffic_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,7 @@ func (device *Device) TCBatch(batch []*TCElement, tcs *TCState) {
for i, elem := range batch {
// process TC Filters
act := TcPass
elem.ParsePacket()
if !elem.Validate() {
if !elem.ParsePacket() || !elem.Validate() {
device.Log.Errorf("Found malformed packet, dropping packet")
act = TcDrop
} else {
Expand Down
37 changes: 34 additions & 3 deletions polyamide/device/traffic_manip.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,25 @@ func (elem *TCElement) InitPacket(ver int, len uint16) {
elem.SetLength(len)
}

func (elem *TCElement) ParsePacket() {
elem.Packet = elem.Buffer[MessageTransportHeaderSize:]
func (elem *TCElement) ParsePacket() bool {
if elem == nil {
return false
}
if len(elem.Packet) == 0 {
if elem.Buffer == nil {
return false
}
elem.Packet = elem.Buffer[MessageTransportHeaderSize:]
}
if !elem.hasPacketHeader() {
return false
}
l := elem.GetLength()
elem.Packet = elem.Buffer[MessageTransportHeaderSize : MessageTransportHeaderSize+l]
if int(l) > len(elem.Packet) {
return false
}
elem.Packet = elem.Packet[:l]
Comment on lines 36 to +40
return true
}

func (elem *TCElement) Incoming() bool {
Expand Down Expand Up @@ -137,6 +152,9 @@ func (elem *TCElement) Validate() bool {
if elem == nil || len(elem.Packet) == 0 {
return false
}
if !elem.hasPacketHeader() {
return false
}
ver := elem.GetIPVersion()
if ver == 4 {
if elem.GetLength() < ipv4.HeaderLen {
Expand All @@ -154,6 +172,19 @@ func (elem *TCElement) Validate() bool {
return true
}

func (elem *TCElement) hasPacketHeader() bool {
if elem == nil || len(elem.Packet) < PolyHeaderSize {
return false
}
ver := elem.GetIPVersion()
if ver == 4 {
return len(elem.Packet) >= ipv4.HeaderLen
} else if ver == 6 {
return len(elem.Packet) >= ipv6.HeaderLen
}
return true
}

func (elem *TCElement) TTLBytes() []byte {
if elem.GetIPVersion() == 4 {
return elem.Packet[8:9]
Expand Down
41 changes: 41 additions & 0 deletions polyamide/device/traffic_manip_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package device

import (
"encoding/binary"
"testing"
)

func TestParsePacketRejectsLengthBeyondReadBuffer(t *testing.T) {
var buf [MaxMessageSize]byte
packet := buf[MessageTransportHeaderSize : MessageTransportHeaderSize+2016]
packet[0] = 6 << 4
binary.BigEndian.PutUint16(packet[IPv6offsetPayloadLength:IPv6offsetPayloadLength+2], 2010)

elem := &TCElement{
Buffer: &buf,
Packet: packet,
}

if elem.ParsePacket() {
t.Fatal("expected oversized packet to be rejected")
}
}

func TestParsePacketTrimsToAdvertisedLength(t *testing.T) {
var buf [MaxMessageSize]byte
packet := buf[MessageTransportHeaderSize : MessageTransportHeaderSize+128]
packet[0] = 6 << 4
binary.BigEndian.PutUint16(packet[IPv6offsetPayloadLength:IPv6offsetPayloadLength+2], 8)

elem := &TCElement{
Buffer: &buf,
Packet: packet,
}

if !elem.ParsePacket() {
t.Fatal("expected valid packet to parse")
}
if len(elem.Packet) != 48 {
t.Fatalf("expected packet length 48, got %d", len(elem.Packet))
}
}
Loading