Lucene search

K
code423n4Code4renaCODE423N4:2023-03-ZKSYNC-FINDINGS-ISSUES-152
HistoryMar 19, 2023 - 12:00 a.m.

DefaultAccount will add system call flag to any call with msg.value

2023-03-1900:00:00
Code4rena
github.com
7
vulnerability
impact
proof of concept
mitigation
defaultaccount
issystem flag
ethereum
evm-like call
system_call_byref
msgvaluesimulator
mask
mimiccall
gasleft
manual review

Lines of code
<https://github.com/code-423n4/2023-03-zksync/blob/main/contracts/libraries/EfficientCall.sol#L134-L145&gt;
<https://github.com/code-423n4/2023-03-zksync/blob/main/contracts/MsgValueSimulator.sol#L22-L29&gt;
<https://github.com/code-423n4/2023-03-zksync/blob/main/contracts/MsgValueSimulator.sol#L62&gt;

Vulnerability details

Impact

As mentioned in the repo’s README.md documentation:

isSystem flag. Whether the call intends a system contracts' function. While most of the system contracts' functions are relatively harmless, accessing some with calldata only may break the invariants of Ethereum

The DefaultAccount will add isSystem flag explicitly to any transaction(call) if the msg.value of the transaction is not zero. These transactions will bypass the onlySystemCall check directly.

onlySystemCall modifier in the README.md documentation:

That's why we wanted to make it clear that users can not invoke potentially dangerous operations by doing a simple EVM-like call. Whenever a user wants to invoke some of the operations which we considered dangerous, they must explicitly provide isSystem flag with them.

Proof of Concept

In the DefaultAccount._execute function, if the to address is not DEPLOYER_SYSTEM_CONTRACT address, it will use the function EfficientCall.rawCall(gas, to, value, data) to forward the call.

In the EfficientCall.rawCall function if the _value param, which is from msg.value, is not zero, it will simulate system_call_byref opcode to call the MsgValueSimulator system contract with the following params:

success := call(msgValueSimulator, callAddr, _value, _address, 0xFFFF, forwardMask, 0)

And the forwardMask will be set to MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT.

Now the context is coming in the MsgValueSimulator.fallback function. It will get the above mask and set it as the isSystemCall param:

isSystemCall = (mask & MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT) != 0;

The isSystemCall param will make the final mimicCall forward the call with the isSystem flag:

EfficientCall.mimicCall(gasleft(), to, _data, msg.sender, false, isSystemCall);

Tools Used

Manual review

Recommended Mitigation Steps

Should let the account choose whether or not to add the system mask in the DefaultAccount._execute function when forwarding the call to the MsgValueSimulator.


The text was updated successfully, but these errors were encountered:

All reactions