🇰🇷 한글 설명
CometBFT의 특정 버전에서 PeerState 구조체를 JSON으로 직렬화할 때 데드락(Deadlock)이 발생하는 취약점입니다. 로그 설정을 디버그 모드로 하거나 RPC를 통해 consensus 상태를 덤프할 때 발생하며, 네트워크 규모에 따라 노드 전체가 중단되거나 특정 통신 채널이 차단될 수 있습니다.
💡 쉬운 설명
프로그램 내부에서 데이터를 처리하는 방식의 오류로 인해 시스템이 멈추거나 응답하지 않는 현상이 발생할 수 있습니다. 특정 명령을 내리거나 로그 설정을 변경할 때 컴퓨터가 무한 대기 상태에 빠질 수 있는 문제입니다.
🇺🇸 원문 (English)
CometBFT is a Byzantine Fault Tolerant (BFT) middleware that takes a state transition machine and replicates it on many machines. An internal modification made in versions 0.34.28 and 0.37.1 to the way struct `PeerState` is serialized to JSON introduced a deadlock when new function MarshallJSON is called. This function can be called from two places. The first is via logs, setting the `consensus` logging module to "debug" level (should not happen in production), and setting the log output format to JSON. The second is via RPC `dump_consensus_state`.
Case 1, which should not be hit in production, will eventually hit the deadlock in most goroutines, effectively halting the node.
In case 2, only the data structures related to the first peer will be deadlocked, together with the thread(s) dealing with the RPC request(s). This means that only one of the channels of communication to the node's peers will be blocked. Eventually the peer will timeout and excluded from the list (typically after 2 minutes). The goroutines involved in the deadlock will not be garbage collected, but they will not interfere with the system after the peer is excluded.
The theoretical worst case for case 2, is a network with only two validator nodes. In this case, each of the nodes only has one `PeerState` struct. If `dump_consensus_state` is called in either node (or both), the chain will halt until the peer connections time out, after which the nodes will reconnect (with different `PeerState` structs) and the chain will progress again. Then, the same process can be repeated.
As the number of nodes in a network increases, and thus, the number of peer struct each node maintains, the possibility of reproducing the perturbation visible with two nodes decreases. Only the first `PeerState` struct will deadlock, and not the others (RPC `dump_consensus_state` accesses them in a for loop, so the deadlock at the first iteration causes the rest of the iterations of that "for" loop to never be reached).
This regression was fixed in versions 0.34.29 and 0.37.2. Some workarounds are available. For case 1 (hitting the deadlock via logs), either don't set the log output to "json", leave at "plain", or don't set the consensus logging module to "debug", leave it at "info" or higher. For case 2 (hitting the deadlock via RPC `dump_consensus_state`), do not expose `dump_consensus_state` RPC endpoint to the public internet (e.g., via rules in one's nginx setup).
📍 영향받는 시스템
CometBFT versions 0.34.28 and 0.37.1
⚔️ 공격 벡터
RPC dump_consensus_state 호출 또는 디버그 로그의 JSON 출력 설정 유도
🛡️ 대응 방법
CometBFT를 0.34.29 또는 0.37.2 이상의 버전으로 업데이트하거나, RPC 엔드포인트를 외부 노출로부터 차단하십시오.
🔧 검증 코드
설치된 CometBFT의 버전을 확인하여 0.34.28 또는 0.37.1인지 점검하십시오.
grep -E 'CometBFT' /path/to/your/binary_or_config 2>/dev/null || echo 'Check installed CometBFT version'