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

SEGV bug in `pkg/server/fsm.go` #2725

Open grandnew opened 10 months ago

grandnew commented 10 months ago

I triggered a SEGV bug when fuzzing gobgp.

The config of the under-test node is as follows, and its IP is 10.0.255.6

[global.config]
  as = 65001
  router-id = "192.168.10.6"

[[neighbors]]
  [neighbors.config]
    neighbor-address = "10.0.255.5"
    peer-as = 64512

The fuzzing node is deployed on 10.0.255.5.

The log snippet around the crash point:

{"Key":"10.0.255.5","State":"BGP_FSM_ESTABLISHED","Topic":"Peer","data":{"Header":{"Marker":null,"Len":19,"Type":4},"Body":{}},"level":"debug","msg":"sent","time":"2023-10-21T09:40:07Z"}
{"Key":"10.0.255.5","Topic":"Peer","attributes":[{"type":1,"value":2},{"type":2,"as_paths":[{"segment_type":2,"num":1,"asns":[64512]}]},{"type":3,"nexthop":"10.0.255.5"},{"type":4,"metric":150}],"level":"debug","msg":"received update","nlri":[{"prefix":"192.168.101.0/24"}],"time":"2023-10-21T09:40:07Z","withdrawals":[]}
{"Nlri":{"prefix":"192.168.101.0/24"},"Topic":"Table","level":"debug","msg":"create Destination","time":"2023-10-21T09:40:07Z"}
{"Nlri":{"prefix":"192.168.101.0/24"},"Topic":"Table","level":"debug","msg":"create Destination","time":"2023-10-21T09:40:07Z"}
{"Data":{"nlri":{"prefix":"192.168.101.0/24"},"attrs":[{"type":1,"value":2},{"type":2,"as_paths":[{"segment_type":2,"num":1,"asns":[64512]}]},{"type":3,"nexthop":"10.0.255.5"},{"type":4,"metric":150}],"age":1697881207,"source-id":"192.168.10.5","neighbor-ip":"10.0.255.5"},"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"From me, ignore","time":"2023-10-21T09:40:07Z"}
{"Key":"10.0.255.5","Topic":"Peer","attributes":[],"level":"debug","msg":"received update","nlri":[],"time":"2023-10-21T09:40:10Z","withdrawals":[{"prefix":"192.168.101.0/24"}]}
{"Key":"192.168.101.0/24","Topic":"Table","level":"debug","msg":"Removing withdrawals","time":"2023-10-21T09:40:10Z"}
{"Data":{"nlri":{"prefix":"192.168.101.0/24"},"attrs":[{"type":1,"value":2},{"type":2,"as_paths":[{"segment_type":2,"num":1,"asns":[64512]}]},{"type":3,"nexthop":"10.0.255.5"},{"type":4,"metric":150}],"age":1697881207,"withdrawal":true,"source-id":"192.168.10.5","neighbor-ip":"10.0.255.5"},"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"From me, ignore","time":"2023-10-21T09:40:10Z"}
{"Key":"10.0.255.5","Topic":"Peer","attributes":[{"type":1,"value":2},{"type":2,"as_paths":[{"segment_type":2,"num":1,"asns":[64512]}]},{"type":3,"nexthop":"10.0.255.5"},{"type":4,"metric":200}],"level":"debug","msg":"received update","nlri":[{"prefix":"192.168.101.0/24"}],"time":"2023-10-21T09:40:13Z","withdrawals":[]}
{"Nlri":{"prefix":"192.168.101.0/24"},"Topic":"Table","level":"debug","msg":"create Destination","time":"2023-10-21T09:40:13Z"}
{"Nlri":{"prefix":"192.168.101.0/24"},"Topic":"Table","level":"debug","msg":"create Destination","time":"2023-10-21T09:40:13Z"}
{"Data":{"nlri":{"prefix":"192.168.101.0/24"},"attrs":[{"type":1,"value":2},{"type":2,"as_paths":[{"segment_type":2,"num":1,"asns":[64512]}]},{"type":3,"nexthop":"10.0.255.5"},{"type":4,"metric":200}],"age":1697881213,"source-id":"192.168.10.5","neighbor-ip":"10.0.255.5"},"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"From me, ignore","time":"2023-10-21T09:40:13Z"}
{"Key":"10.0.255.5","Topic":"Peer","attributes":[],"level":"debug","msg":"received update","nlri":[],"time":"2023-10-21T09:40:16Z","withdrawals":[{"prefix":"192.168.101.0/24"}]}
{"Key":"192.168.101.0/24","Topic":"Table","level":"debug","msg":"Removing withdrawals","time":"2023-10-21T09:40:16Z"}
{"Data":{"nlri":{"prefix":"192.168.101.0/24"},"attrs":[{"type":1,"value":2},{"type":2,"as_paths":[{"segment_type":2,"num":1,"asns":[64512]}]},{"type":3,"nexthop":"10.0.255.5"},{"type":4,"metric":200}],"age":1697881213,"withdrawal":true,"source-id":"192.168.10.5","neighbor-ip":"10.0.255.5"},"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"From me, ignore","time":"2023-10-21T09:40:16Z"}
{"Key":"10.0.255.5","Topic":"Peer","attributes":[{"type":1,"value":2},{"type":2,"as_paths":[{"segment_type":2,"num":1,"asns":[64512]}]},{"type":3,"nexthop":"10.0.255.5"}],"level":"debug","msg":"received update","nlri":[{"prefix":"192.168.102.0/24"}],"time":"2023-10-21T09:40:19Z","withdrawals":[]}
{"Nlri":{"prefix":"192.168.102.0/24"},"Topic":"Table","level":"debug","msg":"create Destination","time":"2023-10-21T09:40:19Z"}
{"Nlri":{"prefix":"192.168.102.0/24"},"Topic":"Table","level":"debug","msg":"create Destination","time":"2023-10-21T09:40:19Z"}
{"Data":{"nlri":{"prefix":"192.168.102.0/24"},"attrs":[{"type":1,"value":2},{"type":2,"as_paths":[{"segment_type":2,"num":1,"asns":[64512]}]},{"type":3,"nexthop":"10.0.255.5"}],"age":1697881219,"source-id":"192.168.10.5","neighbor-ip":"10.0.255.5"},"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"From me, ignore","time":"2023-10-21T09:40:19Z"}
{"Key":"10.0.255.5","Topic":"Peer","attributes":[],"level":"debug","msg":"received update","nlri":[],"time":"2023-10-21T09:40:22Z","withdrawals":[{"prefix":"192.168.102.0/24"}]}
{"Key":"192.168.102.0/24","Topic":"Table","level":"debug","msg":"Removing withdrawals","time":"2023-10-21T09:40:22Z"}
{"Data":{"nlri":{"prefix":"192.168.102.0/24"},"attrs":[{"type":1,"value":2},{"type":2,"as_paths":[{"segment_type":2,"num":1,"asns":[64512]}]},{"type":3,"nexthop":"10.0.255.5"}],"age":1697881219,"withdrawal":true,"source-id":"192.168.10.5","neighbor-ip":"10.0.255.5"},"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"From me, ignore","time":"2023-10-21T09:40:22Z"}
{"Key":"10.0.255.5","Topic":"Peer","attributes":[{"type":1,"value":2},{"type":2,"as_paths":[{"segment_type":2,"num":1,"asns":[64512]}]},{"type":3,"nexthop":"10.0.255.5"}],"level":"debug","msg":"received update","nlri":[{"prefix":"192.168.102.0/24"}],"time":"2023-10-21T09:40:25Z","withdrawals":[]}
{"Nlri":{"prefix":"192.168.102.0/24"},"Topic":"Table","level":"debug","msg":"create Destination","time":"2023-10-21T09:40:25Z"}
{"Nlri":{"prefix":"192.168.102.0/24"},"Topic":"Table","level":"debug","msg":"create Destination","time":"2023-10-21T09:40:25Z"}
{"Data":{"nlri":{"prefix":"192.168.102.0/24"},"attrs":[{"type":1,"value":2},{"type":2,"as_paths":[{"segment_type":2,"num":1,"asns":[64512]}]},{"type":3,"nexthop":"10.0.255.5"}],"age":1697881225,"source-id":"192.168.10.5","neighbor-ip":"10.0.255.5"},"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"From me, ignore","time":"2023-10-21T09:40:25Z"}
{"Key":"10.0.255.5","Topic":"Peer","attributes":[],"level":"debug","msg":"received update","nlri":[],"time":"2023-10-21T09:40:28Z","withdrawals":[{"prefix":"192.168.102.0/24"}]}
{"Key":"192.168.102.0/24","Topic":"Table","level":"debug","msg":"Removing withdrawals","time":"2023-10-21T09:40:28Z"}
{"Data":{"nlri":{"prefix":"192.168.102.0/24"},"attrs":[{"type":1,"value":2},{"type":2,"as_paths":[{"segment_type":2,"num":1,"asns":[64512]}]},{"type":3,"nexthop":"10.0.255.5"}],"age":1697881225,"withdrawal":true,"source-id":"192.168.10.5","neighbor-ip":"10.0.255.5"},"Key":"10.0.255.5","Topic":"Peer","level":"debug","msg":"From me, ignore","time":"2023-10-21T09:40:28Z"}
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x1a pc=0xb1f5e7]

goroutine 413 [running]:
github.com/osrg/gobgp/v3/pkg/server.(*fsmHandler).handlingError(0xc00009fec0?, 0xc00034d0c0?, {0xea7160?, 0xc0003f9140?}, 0x88?)
    github.com/osrg/gobgp/v3/pkg/server/fsm.go:913 +0x27
github.com/osrg/gobgp/v3/pkg/server.(*fsmHandler).recvMessageWithError(0xc00011bce0)
    github.com/osrg/gobgp/v3/pkg/server/fsm.go:1017 +0x685
github.com/osrg/gobgp/v3/pkg/server.(*fsmHandler).recvMessageloop(0xc00011bce0, {0x0?, 0x0?}, 0x0?)
    github.com/osrg/gobgp/v3/pkg/server/fsm.go:1783 +0x5b
created by github.com/osrg/gobgp/v3/pkg/server.(*fsmHandler).established in goroutine 411
    github.com/osrg/gobgp/v3/pkg/server/fsm.go:1805 +0x270

The full logs and network capture are as attached.

SEGV_debugMode.log SEGV_network_capture.pcap.zip

grandnew commented 10 months ago

Dear maintainers, what's the possible reason for this bug? @fragmede @rubenk

fujita commented 10 months ago

You use two GoBGP daemons?

grandnew commented 10 months ago

You use two GoBGP daemons?

No, only the under-test node uses the GoBGP daemon.

fujita commented 10 months ago

What BGP daemon other side?

grandnew commented 10 months ago

What BGP daemon other side?

The other side is a fuzzer that continuously generates BGP packets and sends them to the under-test node for testing. @fujita

abergmann commented 4 months ago

CVE-2023-46565 was assigned to this issue.

matbits commented 3 months ago

Hello together,

I looked into the code and found a possible reason for the segv message (unfortunate I do not have time to test the pcap stream against a fixed version to confirm my assumptions), anyway here are my thoughts:

The function (h *fsmHandler) recvMessageWithError() calls hd.DecodeFromBytes which parses the bytes into BGPHeader, but does not check the type. Later the function recvMessageWithError() calls ParseBGPBody, which actually calls parseBody which checks the header type and if it is unknown, it returns nil and an error. Thus the check for an error is true and it calls handlingError with m being a nil BGPMessage and the function deferences a nil pointer.

What do you think about it, does this make sense? Could this be the reason for the segv?