Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Contract storage size panic on u32 overflow #2672

Closed
gui1117 opened this issue May 23, 2019 · 3 comments · Fixed by #7885
Closed

Contract storage size panic on u32 overflow #2672

gui1117 opened this issue May 23, 2019 · 3 comments · Fixed by #7885
Labels
I2-security The client fails to follow expected, security-sensitive, behaviour.

Comments

@gui1117
Copy link
Contributor

gui1117 commented May 23, 2019

Storage size is u32, and has value of all values size + storage_size_offset. If this exceed u32::max_value() then it currently panics.

Even if chain like Ethereum storage might never reach 4GB it might be the case for some peculiar chain using our framework. Thus I would go to make storage_size being u64.

This would imply some more complex conversion in rent computation but nothing that complicated.

@gui1117 gui1117 added M8-contracts Z1-easy Can be fixed primarily by duplicating and adapting code by an intermediate coder labels May 23, 2019
@gui1117 gui1117 self-assigned this May 23, 2019
@gui1117 gui1117 removed the Z1-easy Can be fixed primarily by duplicating and adapting code by an intermediate coder label May 24, 2019
@gavofyork
Copy link
Member

storage size should remain u32; if anyone ever manages to store more than 4GB of data on-chain, and pays for it, then it's fine to just saturate the total at 2**32-1.

@gui1117
Copy link
Contributor Author

gui1117 commented May 28, 2019

ok, implementation speaking it might not be easier because currently we only decrease/increase storage size on removed/inserted value. Thus we need to keep track of the real storage size otherwise a contract could go to a storage size of u32::max*2 and then remove u32::max size and he would have storage_size=0 but real_storage_size=u32::max. or find another implementation

@gui1117 gui1117 removed their assignment Jul 16, 2019
@athei athei added the I2-security The client fails to follow expected, security-sensitive, behaviour. label Jun 16, 2020
@athei
Copy link
Member

athei commented Jun 16, 2020

ok, implementation speaking it might not be easier because currently we only decrease/increase storage size on removed/inserted value. Thus we need to keep track of the real storage size otherwise a contract could go to a storage size of u32::max*2 and then remove u32::max size and he would have storage_size=0 but real_storage_size=u32::max. or find another implementation

So switching from checked_add to saturating_add would make things worse? With the current code that panics on overflow we are in a situation where any extrinsic that increases the storage size above 4GB is simply invalid. This is usually bad because then no one pays for that invalid transaction. However, in order to make that happen the contract needs to pay a lot of rent.

That said, it might be worthwhile to switch from panic to a regular DispatchError. Given that we agree that we want to cap contracts at 4GB for now.

This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
I2-security The client fails to follow expected, security-sensitive, behaviour.
Projects
Status: No status
3 participants