You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
During the GRANDPA protocol, if vote or commit messages are received which we are unable to process, we add this block to the tracker for future processing. This may occur due to a block not existing in our block tree or that the round in a vote message is greater than our current round. Future processing is triggered when a new block is imported, the tracker then compares the block hash of the new block against the hash included in the messages. When the hashes match the message is passed back to the handler for processing.
There is a potential denial of service (DoS) attack that can exploit the storage of these messages. When a vote is received with a round greater than our current round it will be added to the tracker . An attacker is able to exploit this by repeatedly sending vote messages with rounds much higher than the current round. These votes will be stored in the tacker indefinitely if the hash is not from a block that will not be imported (e.g. a hash of random bytes). Thus, memory will continue to grow indefinitely as the attacker continues to sending malicious votes with high rounds. Each round must be different else it is an equivocatory vote, however round is a uint64 which gives 2^64 different rounds to use.
Furthermore, if there are valid votes received from a future round while our round is behind and we have imported the block associated with the Hash , then these votes will be added to the tracker and never processed. This is due to the fact we only iterate through the tracker when we import a new block, checking the vote hash against the new block hash. Hence, votes for blocks already in the tree will never be processed.
The votes or commits which are stored in the tracker will be stored indefinitely when they have a Hash related to blocks that will never be imported. Since the commit messages are validated and thus will related to finalised blocks, it can be assumed that all commit messages will be processed eventually as all finalised blocks will be imported. However, due to race conditions between storing the messages in the maps and blocks being imported it is possible to have commit messages included in the maps which relate to blocks already imported. Furthermore, a malfunctioning or malicious node may send a vote with a block hash not related to a real block. These block hashes will not be processed and will remain in the tracker indefinitely.
The issue may be partially resolved by ignoring votes with the Round higher than our current Round . Valid nodes will periodically resend votes for the duration of a round, thus the current round votes will eventually be received. This can be implemented in lib/grandpa/vote_message.go::validateMessage().
Also consider setting an expiry time for vote and commit messages that are stored in the tracker. A garbage collector routine may then be used to periodically iterate over the voteMessages and commitMessages maps and delete those that have expired.
The text was updated successfully, but these errors were encountered:
danforbes
changed the title
Insufficient Garbage Collection for GRANDPA Message Tracker
Insufficient Garbage Collection for GRANDPA Message Tracker (GSR-05)
Mar 18, 2022
During the GRANDPA protocol, if vote or commit messages are received which we are unable to process, we add this block to the
tracker
for future processing. This may occur due to a block not existing in our block tree or that the round in a vote message is greater than our current round. Future processing is triggered when a new block is imported, thetracker
then compares the block hash of the new block against the hash included in the messages. When the hashes match the message is passed back to the handler for processing.There is a potential denial of service (DoS) attack that can exploit the storage of these messages. When a vote is received with a round greater than our current round it will be added to the
tracker
. An attacker is able to exploit this by repeatedly sending vote messages with rounds much higher than the current round. These votes will be stored in the tacker indefinitely if the hash is not from a block that will not be imported (e.g. a hash of random bytes). Thus, memory will continue to grow indefinitely as the attacker continues to sending malicious votes with high rounds. Each round must be different else it is an equivocatory vote, howeverround
is auint64
which gives 2^64 different rounds to use.Furthermore, if there are valid votes received from a future round while our round is behind and we have imported the block associated with the
Hash
, then these votes will be added to thetracker
and never processed. This is due to the fact we only iterate through thetracker
when we import a new block, checking the vote hash against the new block hash. Hence, votes for blocks already in the tree will never be processed.The votes or commits which are stored in the
tracker
will be stored indefinitely when they have a Hash related to blocks that will never be imported. Since the commit messages are validated and thus will related to finalised blocks, it can be assumed that all commit messages will be processed eventually as all finalised blocks will be imported. However, due to race conditions between storing the messages in the maps and blocks being imported it is possible to have commit messages included in the maps which relate to blocks already imported. Furthermore, a malfunctioning or malicious node may send a vote with a block hash not related to a real block. These block hashes will not be processed and will remain in thetracker
indefinitely.The issue may be partially resolved by ignoring votes with the
Round
higher than our currentRound
. Valid nodes will periodically resend votes for the duration of a round, thus the current round votes will eventually be received. This can be implemented inlib/grandpa/vote_message.go::validateMessage()
.Also consider setting an expiry time for vote and commit messages that are stored in the
tracker
. A garbage collector routine may then be used to periodically iterate over thevoteMessages
andcommitMessages
maps and delete those that have expired.The text was updated successfully, but these errors were encountered: