From e16d3efb0aa973c7a5591ebbf6baeba6d7bb55d6 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Thu, 26 Sep 2019 18:11:58 -0500 Subject: [PATCH 1/2] check packet length before checking if it's an ipv6 packet, and add some trace level logging whenever a packet is rejected for being too short to parse --- src/tuntap/iface.go | 7 +++++++ src/util/cancellation.go | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/tuntap/iface.go b/src/tuntap/iface.go index 753a8d02..5db9f1ca 100644 --- a/src/tuntap/iface.go +++ b/src/tuntap/iface.go @@ -148,6 +148,11 @@ func (tun *TunAdapter) _handlePacket(recvd []byte, err error) { // Offset the buffer from now on so that we can ignore ethernet frames if // they are present bs := recvd[offset:] + // Check if the packet is long enough to detect if it's an ICMP packet or not + if len(bs) < 7 { + tun.log.Traceln("TUN/TAP iface read undersized unknown packet, length:", len(bs)) + return + } // If we detect an ICMP packet then hand it to the ICMPv6 module if bs[6] == 58 { // Found an ICMPv6 packet - we need to make sure to give ICMPv6 the full @@ -175,6 +180,7 @@ func (tun *TunAdapter) _handlePacket(recvd []byte, err error) { if bs[0]&0xf0 == 0x60 { // Check if we have a fully-sized IPv6 header if len(bs) < 40 { + tun.log.Traceln("TUN/TAP iface read undersized ipv6 packet, length:", len(bs)) return } // Check the packet size @@ -188,6 +194,7 @@ func (tun *TunAdapter) _handlePacket(recvd []byte, err error) { } else if bs[0]&0xf0 == 0x40 { // Check if we have a fully-sized IPv4 header if len(bs) < 20 { + tun.log.Traceln("TUN/TAP iface read undersized ipv6 packet, length:", len(bs)) return } // Check the packet size diff --git a/src/util/cancellation.go b/src/util/cancellation.go index 6b2002c8..1f6d1658 100644 --- a/src/util/cancellation.go +++ b/src/util/cancellation.go @@ -11,8 +11,8 @@ import ( // This is and is similar to a context, but with an error to specify the reason for the cancellation. type Cancellation interface { Finished() <-chan struct{} // Finished returns a channel which will be closed when Cancellation.Cancel is first called. - Cancel(error) error // Cancel closes the channel returned by Finished and sets the error returned by error, or else returns the existing error if the Cancellation has already run. - Error() error // Error returns the error provided to Cancel, or nil if no error has been provided. + Cancel(error) error // Cancel closes the channel returned by Finished and sets the error returned by error, or else returns the existing error if the Cancellation has already run. + Error() error // Error returns the error provided to Cancel, or nil if no error has been provided. } // CancellationFinalized is an error returned if a cancellation object was garbage collected and the finalizer was run. From 0f99d590a1c2592e333a51a71b4536aebaea5cc0 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Thu, 26 Sep 2019 18:15:26 -0500 Subject: [PATCH 2/2] typo, ipv6->ipv4 --- src/tuntap/iface.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tuntap/iface.go b/src/tuntap/iface.go index 5db9f1ca..0da99631 100644 --- a/src/tuntap/iface.go +++ b/src/tuntap/iface.go @@ -194,7 +194,7 @@ func (tun *TunAdapter) _handlePacket(recvd []byte, err error) { } else if bs[0]&0xf0 == 0x40 { // Check if we have a fully-sized IPv4 header if len(bs) < 20 { - tun.log.Traceln("TUN/TAP iface read undersized ipv6 packet, length:", len(bs)) + tun.log.Traceln("TUN/TAP iface read undersized ipv4 packet, length:", len(bs)) return } // Check the packet size