mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Ignore the length field when processing the experiment extension header.
Reported-by: syzbot+9970c3c1f330bc544966@syzkaller.appspotmail.com PiperOrigin-RevId: 703588249
This commit is contained in:
committed by
gVisor bot
parent
dc24ae5c71
commit
ddaa99e5d4
@@ -595,7 +595,7 @@ func (i *IPv6PayloadIterator) Next() (IPv6PayloadHeader, bool, error) {
|
||||
// Is the header we are parsing a known extension header?
|
||||
switch i.nextHdrIdentifier {
|
||||
case IPv6HopByHopOptionsExtHdrIdentifier:
|
||||
nextHdrIdentifier, view, err := i.nextHeaderData(false /* fragmentHdr */, nil)
|
||||
nextHdrIdentifier, view, err := i.nextHeaderData(false /* ignoreLength */, nil)
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
@@ -603,7 +603,7 @@ func (i *IPv6PayloadIterator) Next() (IPv6PayloadHeader, bool, error) {
|
||||
i.nextHdrIdentifier = nextHdrIdentifier
|
||||
return IPv6HopByHopOptionsExtHdr{ipv6OptionsExtHdr{view}}, false, nil
|
||||
case IPv6RoutingExtHdrIdentifier:
|
||||
nextHdrIdentifier, view, err := i.nextHeaderData(false /* fragmentHdr */, nil)
|
||||
nextHdrIdentifier, view, err := i.nextHeaderData(false /* ignoreLength */, nil)
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
@@ -614,7 +614,7 @@ func (i *IPv6PayloadIterator) Next() (IPv6PayloadHeader, bool, error) {
|
||||
var data [6]byte
|
||||
// We ignore the returned bytes because we know the fragment extension
|
||||
// header specific data will fit in data.
|
||||
nextHdrIdentifier, _, err := i.nextHeaderData(true /* fragmentHdr */, data[:])
|
||||
nextHdrIdentifier, _, err := i.nextHeaderData(true /* ignoreLength */, data[:])
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
@@ -633,7 +633,7 @@ func (i *IPv6PayloadIterator) Next() (IPv6PayloadHeader, bool, error) {
|
||||
i.nextHdrIdentifier = nextHdrIdentifier
|
||||
return fragmentExtHdr, false, nil
|
||||
case IPv6DestinationOptionsExtHdrIdentifier:
|
||||
nextHdrIdentifier, view, err := i.nextHeaderData(false /* fragmentHdr */, nil)
|
||||
nextHdrIdentifier, view, err := i.nextHeaderData(false /* ignoreLength */, nil)
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
@@ -642,7 +642,7 @@ func (i *IPv6PayloadIterator) Next() (IPv6PayloadHeader, bool, error) {
|
||||
return IPv6DestinationOptionsExtHdr{ipv6OptionsExtHdr{view}}, false, nil
|
||||
case IPv6ExperimentExtHdrIdentifier:
|
||||
var data [IPv6ExperimentHdrLength - ipv6ExperimentHdrValueOffset]byte
|
||||
nextHdrIdentifier, _, err := i.nextHeaderData(false /* fragmentHdr */, data[:])
|
||||
nextHdrIdentifier, _, err := i.nextHeaderData(true /* ignoreLength */, data[:])
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
@@ -670,14 +670,14 @@ func (i *IPv6PayloadIterator) NextHeaderIdentifier() IPv6ExtensionHeaderIdentifi
|
||||
|
||||
// nextHeaderData returns the extension header's Next Header field and raw data.
|
||||
//
|
||||
// fragmentHdr indicates that the extension header being parsed is the Fragment
|
||||
// extension header so the Length field should be ignored as it is Reserved
|
||||
// for the Fragment extension header.
|
||||
// ignoreLength indicates that the extension header being parsed should ignore
|
||||
// the Length field as it is reserved. This is for the Fragment and Experiment
|
||||
// extension headers.
|
||||
//
|
||||
// If bytes is not nil, extension header specific data will be read into bytes
|
||||
// if it has enough capacity. If bytes is provided but does not have enough
|
||||
// capacity for the data, nextHeaderData will panic.
|
||||
func (i *IPv6PayloadIterator) nextHeaderData(fragmentHdr bool, bytes []byte) (IPv6ExtensionHeaderIdentifier, *buffer.View, error) {
|
||||
func (i *IPv6PayloadIterator) nextHeaderData(ignoreLength bool, bytes []byte) (IPv6ExtensionHeaderIdentifier, *buffer.View, error) {
|
||||
// We ignore the number of bytes read because we know we will only ever read
|
||||
// at max 1 bytes since rune has a length of 1. If we read 0 bytes, the Read
|
||||
// would return io.EOF to indicate that io.Reader has reached the end of the
|
||||
@@ -693,13 +693,13 @@ func (i *IPv6PayloadIterator) nextHeaderData(fragmentHdr bool, bytes []byte) (IP
|
||||
length, err = rdr.ReadByte()
|
||||
|
||||
if err != nil {
|
||||
if fragmentHdr {
|
||||
if ignoreLength {
|
||||
return 0, nil, fmt.Errorf("error when reading the Length field for extension header with id = %d: %w", i.nextHdrIdentifier, err)
|
||||
}
|
||||
|
||||
return 0, nil, fmt.Errorf("error when reading the Reserved field for extension header with id = %d: %w", i.nextHdrIdentifier, err)
|
||||
}
|
||||
if fragmentHdr {
|
||||
if ignoreLength {
|
||||
length = 0
|
||||
}
|
||||
|
||||
@@ -715,7 +715,7 @@ func (i *IPv6PayloadIterator) nextHeaderData(fragmentHdr bool, bytes []byte) (IP
|
||||
i.nextOffset += uint32((length + 1) * ipv6ExtHdrLenBytesPerUnit)
|
||||
|
||||
bytesLen := int(length)*ipv6ExtHdrLenBytesPerUnit + ipv6ExtHdrLenBytesExcluded
|
||||
if bytes != nil {
|
||||
if ignoreLength {
|
||||
if n := len(bytes); n < bytesLen {
|
||||
panic(fmt.Sprintf("bytes only has space for %d bytes but need space for %d bytes (length = %d) for extension header with id = %d", n, bytesLen, length, i.nextHdrIdentifier))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user