Skip to content

Patch incorrect balance update & DoS attack vector

Critical
hanchon published GHSA-68fc-7mhg-6f6c Jul 5, 2024

Package

gomod github.com/evmos/evmos (Go)

Affected versions

<= 18.1.0

Patched versions

>= 19.0.0

Description

Summary

This advisory board aims to describe and address a two vulnerabilities found in the Evmos codebase.

  1. A bug causes discrepancies between EVM and bank module balances during precompile calls. The fix comprises explicitly updating balances in the stateDB during such transactions. It also includes the addition of a new journal entry to allow to revert precompile-related state changes
  2. The claimRewards method on the distribution precompile is vulnerable of a DoS attack.

1. Incorrect balance update

Details

Within the precompiles, we have identified a bug which results in a discrepancy between the balance of an account in the EVM and the bank module. This is the special case in which:

  • a precompile contract is called from a smart contract
  • the called precompile contract method changes an account's balance
  • within the transaction that calls the precompile, the account affected by the precompile call changes its state (besides the changes performed by the precompile contract call).

For example, calling the delegate function of the staking precompile under this scenario:

  • the smart contract function to call is a method that increases a counter variable before the precompile call and decreases after the precompile call
  • the smart contract address is the delegator

Consequently, the smart contract state object has two sources of state update:

  • the bank module when calling the precompile delegate function
  • the state on the EVM when modifying the counter variable of the contract

When this happens, the balance on the bank module and the EVM are different. Currently, the application considers the EVM state as the source of truth, because this is an EVM transaction. This results in improper balance after a precompile transaction, where its balance remains unchanged during this transaction that should have decreased its balance.

Fix

When calling precompiles methods that change accounts balances from a smart contract, the application should update explicitly the balance of the affected account/s on the stateDB.

Severity

Based on ImmuneFi Severity Classification System the severity was evaluated to Critical since the attack could have lead to direct loss of funds.

2. DoS attack vector

Details

A vulnerability was identified in the evmos Distribution precompile that causes an out-of-memory condition, resulting in a node denial-of-service (DoS). Testing revealed that it was possible to trigger this vulnerability without the need to deploy a smart contract, or hold a balance on the network

The claimRewards function, accessible via the Distribution precompile, allows the caller to specify an arbitrary maxRetrieval value that is later passed to the staking module's GetDelegatorValidators function. GetDelegatorValidators directly uses maxRetrieval during a call to make([]types.Validator, maxRetrieve), which allocates a significant amount of memory, leading to an irrecoverable out-of-memory issue. The Distribution precompile makes a claimRewards function available, allowing a delegator to claim rewards from multiple validators. It accepts two arguments: the delegator address delegatorAddr) and the maximum number of validators to retrieve rewards from maxRetrieve). After parsing these arguments from the call's calldata, the staking module's GetDelegatorValidators is called.

In the staking module's GetDelegatorValidators function, the maxRetrieve amount is used directly during a call to make().

A malicious actor can call the Distribution precompile's claimRewards with maxRetrieval = 0xffffffff (max uint32) to allocate a large amount of memory, which triggers a denial of service condition

Fix

Use the MaxValidators number from the module parameters and restrict the maxRetrieve to that value.

Patches

The issue has been patched in versions >=VXX0.0

Severity

Critical

CVE ID

No known CVE

Weaknesses

No CWEs

Credits