diff --git a/go/border/rpkt/extns.go b/go/border/rpkt/extns.go index 2dee7e60a1..c636e6a26c 100644 --- a/go/border/rpkt/extns.go +++ b/go/border/rpkt/extns.go @@ -18,6 +18,7 @@ package rpkt import ( + "github.com/scionproto/scion/go/lib/assert" "github.com/scionproto/scion/go/lib/common" "github.com/scionproto/scion/go/lib/scmp" "github.com/scionproto/scion/go/lib/serrors" @@ -36,11 +37,16 @@ type rExtension interface { const ( // FIXME(kormat): remove when generic header walker is implemented. ErrExtChainTooLong common.ErrMsg = "Extension header chain longer than packet" + ErrExtChainCorrupt common.ErrMsg = "Extension header specifies invalid size" ) // extnParseHBH parses a specified hop-by-hop extension in a packet. func (rp *RtrPkt) extnParseHBH(extType common.ExtnType, start, end, pos int) (rExtension, error) { + if assert.On { + assert.Must(end-start+common.ExtnSubHdrLen >= common.LineLen, + "Extension must be at least one line length") + } switch { case extType == common.ExtnSCMPType: return rSCMPExtFromRaw(rp, start, end) diff --git a/go/border/rpkt/parse.go b/go/border/rpkt/parse.go index 57bbf98be3..9c4cf68bd7 100644 --- a/go/border/rpkt/parse.go +++ b/go/border/rpkt/parse.go @@ -118,10 +118,19 @@ func (rp *RtrPkt) parseHopExtns() error { if currHdr != common.HopByHopClass { // Reached end2end header or L4 protocol break } + if *offset+2 >= len(rp.Raw) { + return common.NewBasicError(ErrExtChainTooLong, nil, "curr", *offset, "max", + len(rp.Raw)) + } currExtn := common.ExtnType{Class: currHdr, Type: rp.Raw[*offset+2]} hdrLen := int(rp.Raw[*offset+1]) * common.LineLen + start := *offset + common.ExtnSubHdrLen + end := *offset + hdrLen + if start >= end || end > len(rp.Raw) { + return common.NewBasicError(ErrExtChainCorrupt, nil, "start", start, "end", end) + } e, err := rp.extnParseHBH( - currExtn, *offset+common.ExtnSubHdrLen, *offset+hdrLen, len(rp.idxs.hbhExt)) + currExtn, start, end, len(rp.idxs.hbhExt)) if err != nil { return err }