Please enable Javascript to view the contents

Ethermint CVE-2021-25837 解析

 ·  ☕ 1 分钟

合约中Storage缓存的生命周期与交易的处理周期不一致:一个合约的Storage会在当前区块中该合约初次被调用时从KVStore读入内存。之后再次调用该合约操作Storage时,会优先从内存中读写。
当交易成功后,会将内存中的Storage写回KVStore,并在Endblock阶段清空内存中的Storage。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
func (so *stateObject) GetState(db ethstate.Database, key ethcmn.Hash) ethcmn.Hash {
   prefixKey := so.GetStorageByAddressKey(key.Bytes())
 
   // if we have a dirty value for this state entry, return it
   idx, dirty := so.keyToDirtyStorageIndex[prefixKey]
   if dirty {
       return so.dirtyStorage[idx].Value
   }
 
   // otherwise return the entry's original value
   value := so.GetCommittedState(db, key)
   return value
}

交易处理过程中对KVStore进行的读写实际发生在msCache缓存上。只有当该交易中的所有msg都被处理成功时,才会将msCache缓存里的更改写入deliverState。并在Commit阶段,将deliverState中发生的状态更改写入主状态。如果对一笔交易的处理在EVM执行成功后失败,那么Storage缓存和deliverState将不再同步。被污染的Storage缓存会对该区块内后续交易造成影响。

待填坑…

分享