mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
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
This commit is contained in:
committed by
gVisor bot
parent
97406b20a1
commit
c55e5bda4d
@@ -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:
|
||||
|
||||
@@ -212,6 +212,31 @@ func TestIPv6OptionsExtHdrIterErr(t *testing.T) {
|
||||
bytes: []byte{1, 3},
|
||||
err: io.ErrUnexpectedEOF,
|
||||
},
|
||||
{
|
||||
name: "Router alert without data",
|
||||
bytes: []byte{byte(ipv6RouterAlertHopByHopOptionIdentifier), 0},
|
||||
err: ErrMalformedIPv6ExtHdrOption,
|
||||
},
|
||||
{
|
||||
name: "Router alert with partial data",
|
||||
bytes: []byte{byte(ipv6RouterAlertHopByHopOptionIdentifier), 1, 1},
|
||||
err: ErrMalformedIPv6ExtHdrOption,
|
||||
},
|
||||
{
|
||||
name: "Router alert with partial data and Pad1",
|
||||
bytes: []byte{byte(ipv6RouterAlertHopByHopOptionIdentifier), 1, 1, 0},
|
||||
err: ErrMalformedIPv6ExtHdrOption,
|
||||
},
|
||||
{
|
||||
name: "Router alert with extra data",
|
||||
bytes: []byte{byte(ipv6RouterAlertHopByHopOptionIdentifier), 3, 1, 2, 3},
|
||||
err: ErrMalformedIPv6ExtHdrOption,
|
||||
},
|
||||
{
|
||||
name: "Router alert with missing data",
|
||||
bytes: []byte{byte(ipv6RouterAlertHopByHopOptionIdentifier), 1},
|
||||
err: io.ErrUnexpectedEOF,
|
||||
},
|
||||
}
|
||||
|
||||
check := func(t *testing.T, it IPv6OptionsExtHdrOptionsIterator, expectedErr error) {
|
||||
|
||||
Reference in New Issue
Block a user