summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/header/ipv6_extension_headers.go
diff options
context:
space:
mode:
authorGhanan Gowripalan <ghanan@google.com>2020-12-15 17:43:38 -0800
committergVisor bot <gvisor-bot@google.com>2020-12-15 17:45:22 -0800
commitc55e5bda4d4590c84c6210b78c4b44c849f4400a (patch)
treeb211f8b65b5358874d70f9e723dbca352548c20c /pkg/tcpip/header/ipv6_extension_headers.go
parent97406b20a1551ddc8d1884d11d81b958b829afae (diff)
Validate router alert's data length
RFC 2711 specifies that the router alert's length field is always 2 so we should make sure only 2 bytes are read from a router alert option's data field. Test: header.TestIPv6OptionsExtHdrIterErr PiperOrigin-RevId: 347727876
Diffstat (limited to 'pkg/tcpip/header/ipv6_extension_headers.go')
-rw-r--r--pkg/tcpip/header/ipv6_extension_headers.go18
1 files changed, 14 insertions, 4 deletions
diff --git a/pkg/tcpip/header/ipv6_extension_headers.go b/pkg/tcpip/header/ipv6_extension_headers.go
index 1fbb2cc98..f18981332 100644
--- a/pkg/tcpip/header/ipv6_extension_headers.go
+++ b/pkg/tcpip/header/ipv6_extension_headers.go
@@ -18,6 +18,7 @@ import (
"bufio"
"bytes"
"encoding/binary"
+ "errors"
"fmt"
"io"
"math"
@@ -274,6 +275,10 @@ func ipv6UnknownActionFromIdentifier(id IPv6ExtHdrOptionIdentifier) IPv6OptionUn
return IPv6OptionUnknownAction((id & ipv6UnknownExtHdrOptionActionMask) >> ipv6UnknownExtHdrOptionActionShift)
}
+// ErrMalformedIPv6ExtHdrOption indicates that an IPv6 extension header option
+// is malformed.
+var ErrMalformedIPv6ExtHdrOption = errors.New("malformed IPv6 extension header option")
+
// IPv6UnknownExtHdrOption holds the identifier and data for an IPv6 extension
// header option that is unknown by the parsing utilities.
type IPv6UnknownExtHdrOption struct {
@@ -351,10 +356,15 @@ func (i *IPv6OptionsExtHdrOptionsIterator) Next() (IPv6ExtHdrOption, bool, error
continue
case ipv6RouterAlertHopByHopOptionIdentifier:
var routerAlertValue [ipv6RouterAlertPayloadLength]byte
- if n, err := i.reader.Read(routerAlertValue[:]); err != nil {
- panic(fmt.Sprintf("error when reading RouterAlert option's data bytes: %s", err))
- } else if n != ipv6RouterAlertPayloadLength {
- return nil, true, fmt.Errorf("read %d bytes for RouterAlert option, expected %d", n, ipv6RouterAlertPayloadLength)
+ if n, err := io.ReadFull(&i.reader, routerAlertValue[:]); err != nil {
+ switch err {
+ case io.EOF, io.ErrUnexpectedEOF:
+ return nil, true, fmt.Errorf("got invalid length (%d) for router alert option (want = %d): %w", length, ipv6RouterAlertPayloadLength, ErrMalformedIPv6ExtHdrOption)
+ default:
+ return nil, true, fmt.Errorf("read %d out of %d option data bytes for router alert option: %w", n, ipv6RouterAlertPayloadLength, err)
+ }
+ } else if n != int(length) {
+ return nil, true, fmt.Errorf("got invalid length (%d) for router alert option (want = %d): %w", length, ipv6RouterAlertPayloadLength, ErrMalformedIPv6ExtHdrOption)
}
return &IPv6RouterAlertOption{Value: IPv6RouterAlertValue(binary.BigEndian.Uint16(routerAlertValue[:]))}, false, nil
default: