mirror of https://github.com/status-im/nim-eth.git
Security/RLPx: Fix crash when peer sends out of bounds message id
Closes [nimbus-eth1#767](https://github.com/status-im/nimbus-eth1/issues/767). Crashes occur when certain invalid RLPx messages are received from a peer. Specifically, `msgId` out of range. Because any peer can easily trigger this crash, we'd consider it a DOS vulnerability if Nimbus-eth1 was in general use. We noticed when syncing to Goerli, there were some rare crashes with this exception. It turned out one peer with custom code, perhaps malfunctioning, was sending these messages if we were unlucky enough to connect to it. `invokeThunk` is called from `dispatchMessages` and checks the range of `msgId`. It correctly recognise that it's out of range, raises and exception and produces a message. Job done. Except the code in `dispatchMessage` treats all that as a warning instead of error, and continues to process the message. A bit lower down, `msgId` is used again without a range check. The trivial fix is to check array bounds before access. -- ps. Here's the stack trace ("reraised" sections hidden): ``` WRN 2021-11-08 21:29:33.238+00:00 Error while handling RLPx message topics="rlpx" tid=2003472 file=rlpx.nim:607 peer=Node[<IP>:45456] msg=45 err="RLPx message with an invalid id 45 on a connection supporting eth,snap" /home/jamie/Status/nimbus-eth1/nimbus/p2p/chain/chain_desc.nim(437) main /home/jamie/Status/nimbus-eth1/nimbus/p2p/chain/chain_desc.nim(430) NimMain /home/jamie/Status/nimbus-eth1/nimbus/nimbus.nim(258) process /home/jamie/Status/nimbus-eth1/vendor/nim-chronos/chronos/asyncloop.nim(279) poll /home/jamie/Status/nimbus-eth1/vendor/nim-chronos/chronos/asyncmacro2.nim(74) colonanonymous /home/jamie/Status/nimbus-eth1/vendor/nim-eth/eth/p2p/rlpx.nim(1218) rlpxAccept /home/jamie/Status/nimbus-eth1/vendor/nim-chronos/chronos/asyncmacro2.nim(101) postHelloSteps /home/jamie/Status/nimbus-eth1/vendor/nim-chronos/chronos/asyncmacro2.nim(74) colonanonymous /home/jamie/Status/nimbus-eth1/vendor/nim-eth/eth/p2p/rlpx.nim(985) postHelloSteps /home/jamie/Status/nimbus-eth1/vendor/nim-chronos/chronos/asyncmacro2.nim(101) dispatchMessages /home/jamie/Status/nimbus-eth1/vendor/nim-chronos/chronos/asyncmacro2.nim(77) colonanonymous /home/jamie/Status/nimbus-eth1/vendor/nim-eth/eth/p2p/rlpx.nim(614) dispatchMessages /home/jamie/Status/nimbus-eth1/vendor/nimbus-build-system/vendor/Nim/lib/system/chcks.nim(23) raiseIndexError2 /home/jamie/Status/nimbus-eth1/vendor/nimbus-build-system/vendor/Nim/lib/system/fatal.nim(49) sysFatal [[reraised from: ... ]] [[reraised from: ... ]] [[reraised from: ... ]] [[reraised from: ... ]] Error: unhandled exception: index 45 not in 0 .. 40 [IndexError] ``` Signed-off-by: Jamie Lokier <jamie@shareable.org>
This commit is contained in:
parent
ae0574fe61
commit
6a8d49e4c0
|
@ -611,7 +611,8 @@ proc dispatchMessages*(peer: Peer) {.async.} =
|
||||||
# The documentation will need to be updated, explaning the fact that
|
# The documentation will need to be updated, explaning the fact that
|
||||||
# nextMsg will be resolved only if the message handler has executed
|
# nextMsg will be resolved only if the message handler has executed
|
||||||
# successfully.
|
# successfully.
|
||||||
if peer.awaitedMessages[msgId] != nil:
|
if msgId >= 0 and msgId < peer.awaitedMessages.len and
|
||||||
|
peer.awaitedMessages[msgId] != nil:
|
||||||
let msgInfo = peer.dispatcher.messages[msgId]
|
let msgInfo = peer.dispatcher.messages[msgId]
|
||||||
try:
|
try:
|
||||||
(msgInfo.nextMsgResolver)(msgData, peer.awaitedMessages[msgId])
|
(msgInfo.nextMsgResolver)(msgData, peer.awaitedMessages[msgId])
|
||||||
|
|
Loading…
Reference in New Issue